UML sequence diagram: How to draw creating an array of objects? - uml

In a UML sequence diagram, how do I draw the process of creating an array of objects? E.g. (simplest case):
object1.function = function() {
return [new Object2(), new Object2()];
};
I presume that I just add new participants in order (as in the diagram below), is that correct? But is there any way to emphasize that they are elements of an array?
Thanks in advance.
var Object1 = function() {};
var Object2 = function() {};
var object1 = new Object1();
object1.function = function() {
return [new Object2(), new Object2()];
};
alert( object1.function() ); // [object Object],[object Object]

Yes, it's simply that you draw two life lines in your example. Each represents one of the returned instances.
However, if you are creating many instances at once it would in most cases be enough to show a single instance as life line and add a note about the remaining ones. I would refrain from artificial presentation of some stack-like instance blocks. It would be possible when you use stereotyped and define the representation in a guideline along with the profile. That depends on your business domain. I usually stick to Occam.

Related

How to access Object3D material after adding the GLTF

I want to duplicate my GLTF models with different positions/colors dynamically, to do so I have done:
const L_4_G = new Object3D();
...
const multiLoad_4 = (result, position) => {
const model = result.scene.children[0];
model.position.copy(position);
model.scale.set(0.05, 0.05, 0.05);
//
L_4_G.add(model.clone())
scene.add(model);
};
...
function duplicateModel4() {
L_4_G.translateX(-1.2)
L_4_G.translateY(0.0)//0.48
L_4_G.translateZ(1.2)
L_4_G.rotateY(Math.PI / 2);
scene.add(L_4_G);
}
I didn't find out how can I change the Object3D color from the documentation, can you please tell me how can I do that? thanks in advance.
Here is the full code that I'm using, and here are the models
Update
I have seen this solution, to store a set of colors in the object's userData and choose the color later:
L_2_G.userData.colors = {green : #00FF00, red : ..., ...}
L_2_G.children[0].material.color(userData.colors["green"])
But I'm getting an error that children[0] undefined, but I can see that this object has a child and a material, and color via the console: console.log(L_2_G.children), console.log(L_2_G.children.length)--> 0
Also I have tried getObjectByName as explained here:
scene.getObjectByName(name).children[0].material.color.set(color);
which also reslts: children[0] is undefined, scene.getObjectByName(name).children.length is 0.
THREE.Object3D is a base class for anything that can go in a scene graph, including lights, cameras, and empty objects. Not all Object3D instances have geometry or materials. You may be looking for the THREE.Mesh subclass which does have materials and colors.
In general, code like getObjectByName(...) and model = result.scene.children[0] is very content-specific. The file might contain many nested objects, and .children[0] just grabs the first part. It's usually best to traverse the scene graph instead, looking for the objects you want to modify (e.g. looking for all Meshes, or Meshes with a particular name).
const model = result.scene;
model.traverse((object) => {
if (object.isMesh) {
object.material.color.setHex( 0x404040 );
}
});
Then you can either add the entire group to your scene (scene.add(model)), or just add parts of it. Keep in mind that adding meshes to a new parent removes them from their previous parent, and you shouldn't do that while traversing the previous parent. Instead you can make a list of meshes, and add them in a second step:
const meshes = [];
result.scene.traverse((object) => {
if (object.isMesh) {
meshes.push(object);
}
});
for (const mesh of meshes) {
scene.add(mesh);
}
Finally, the position of an object is inherited from its parents. By removing the object from its original parents you might change its position in the scene. If you are planing to assign a new position to the object anyway, that is fine.

Any helper methods for walking through the model tree?

I have a requirement to traverse the model tree and at each node perform some business logic, I was wondering if there are any helper methods that I could use that will help with moving through the nodes. Such as breadth first search or depth first search or even simple methods for getting a nodes children and parents?
Also methods for finding leaf nodes would be very helpful.
(Also if possible it would be great if these where provided in javascript rather than ES6, I know Phillipe Leefsma has a blog article that has a piece of code for finding leaf nodes but it is in ES6 and I can't seem to get it converted back to Javascript)
Any help is greatly appreciated.
The method of getting all the children given an instance tree and a node is
instanceTree.enumNodeChildren(node, callback) where all the children dbids are in the callback.
To traverse through the tree, first get the instancee tree and the root id:
var instanceTree = viewer.model.getData().instanceTree;
var rootId = this.rootId = instanceTree.getRootId();
Then the best way is using breadth-first search:
function getAlldbIds (rootId) {
var alldbId = [];
if (!rootId) {
return alldbId;
}
var queue = [];
queue.push(rootId);
while (queue.length > 0) {
var node = queue.shift();
alldbId.push(node);
instanceTree.enumNodeChildren(node, function(childrenIds) {
queue.push(childrenIds);
});
}
return alldbId;
}
You can modify your method to optimize for performance.
Read more about it here: https://forge.autodesk.com/cloud_and_mobile/2015/12/select-all-elements-in-the-viewer-with-view-and-data-api-with-javascript.html

Select and manipulate particular paths within a path group fabric.js

I am making an app that involves shapes like cylinders and boxes, and need to be able to do this with fabric.js. I know about three.js but for my purposes, it must be in 2D.
Initially I thought I would just create them in 3D software and render images which can then be added to the canvas, which I did successfully...
However, I have run into a hurdle where fabric only allows patterns to be filled onto paths or objects (rect, circle etc.)....not images (png).
Since I absolutely need patterns, I now need to create these cylinders in SVG. I have gotten as far as making the cylinders in Illustrator, saving them as SVG's and then using them on the canvas, then adding fill patterns on them. So far so good.
Now I want to be able to fill a different pattern for the top of the cylinder, and a different pattern to the side BUT still have it as one object.
So...How can I select and manipulate particular paths within a path group? Is there anyway to give each path within the group a custom attribute (eg. name) which I can then target? Do I need to create two seperate SVG files and then add them seperately, and if so, how can I do this and still have it as one object?
Here's how I am adding the svg to the canvas...
fabric.loadSVGFromURL("/shapes/50-250R.png", function(objects) {
var oImg = fabric.util.groupSVGElements(objects);
oImg.perPixelTargetFind = true;
oImg.targetFindTolerance = 4;
oImg.componentType = "Shape";
oImg.lockUniScaling = true;
oImg.lockScalingX = true;
oImg.lockScalingY = true;
oImg.setControlsVisibility({'tl': false, 'tr': false, 'bl': false, 'br': false});
canvas.add(oImg);
canvas.renderAll();
});
Here is how I am adding the pattern...
var textureIMG = new Image;
textureIMG.crossOrigin = "anonymous";
textureIMG.src = texture.image;
obj.setFill(); //For some reason, the fill doesn't happen without this line.
var pattern = new fabric.Pattern({
source: textureIMG,
repeat: 'repeat'
});
if (obj instanceof fabric.PathGroup) {
obj.getObjects().forEach(function(o) {
o.setFill(pattern);
});
} else {
obj.setFill(pattern);
}
canvas.renderAll();
Thanks in advance.
So I managed to figure this out. Each path within the path group is stored in the 'paths' array of the object.
I can now add a pattern to the top of the cylinder using...
var obj = canvas.getActiveObject();
obj.paths[0].fill = patternOne;
and to the sides using...
obj.paths[1].fill = patternTwo;

Phaser.io - Load objects from Tiled

I'm new to phaser, and for the past few days I've been trying to make a really simple game, platformer-style, where the player must navigate to certain areas before being able to exit the level.
I have the basics running, but now I can't seem to figure out how to check if the player is in those areas.
The relevant part of the code so far is as follows:
var game = new Phaser.Game(800, 600, Phaser.AUTO, "mygame", {
preload: preload,
create: create,
update: update,
render: render
});
function preload() {
game.load.tilemap("questMap", "assets/quest.json", null, Phaser.Tilemap.TILED_JSON);
game.load.image("tilesheet", "assets/tilesheet.png");
game.load.image("npc", "assets/npc.png");
game.load.spritesheet("player", "assets/player.png", 64, 64);
}
var map;
var tileset;
var groundBg;
var props;
var houses;
var houseProps;
var npc;
var ground;
var areas;
var player;
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.stage.backgroundColor = "#A8DBFF";
map = game.add.tilemap("questMap");
map.addTilesetImage("tilesheet");
map.addTilesetImage("npc");
ground = map.createLayer("ground");
groundBg = map.createLayer("groundbg");
props = map.createLayer("props");
houses = map.createLayer("houses");
houseProps = map.createLayer("houseprops");
npc = map.createLayer("npc");
map.setCollisionBetween(1, 5000);
ground.resizeWorld();
Not too pretty, I know.
I've created the map with tiled and there are a lot of small props and decorative tiles, hence the multiple "map.createLayer()" calls. The only one with collision is the ground layer.
Now, on my Tiled file, I've created an Object layer and drawn small rectangles on the areas I want to check if the player is in. I thought this was going to be an easy process but I can't seem to figure out how to load those areas into Phaser, and then check if the player is within bounds.
Googling has given me some results, but none seem to fit, as they usually cover how to add a sprite to an object, which in this case does not apply.
I simply need that small area to exist and check if the player is there. I've also given names to each of those rectangles in Tiled, via the custom properties tab.
I would try using a transparent image as the area you wish to check if your sprite is over and use
if(sprite1.overlap(transparentImage)){
//do something
}

Nhibernate doesn't save hasManyToMany data

Here are my mappings for Complex and Dish :
public class ComplexMapping:ClassMap<Complex>
{
public ComplexMapping()
{
Table("ComplexTable");
Id(comp => comp.Id,"ComplexId").GeneratedBy.Identity();
Map(comp => comp.Name,"Name").Not.Nullable();
Map(comp => comp.Subscribe, "DescriptionComplex");
HasManyToMany(comp => comp.ScrollOfDish)
.Table("ComplexDish")
.ParentKeyColumn("ComplexId")
.ChildKeyColumn("DishId").Cascade.All();
}
}
public class DishMapping:ClassMap<Dish>
{
public DishMapping()
{
Table("DishTable");
Id(dish => dish.Id, "DishId").GeneratedBy.Identity();
Map(dish => dish.Name);
Map(dish => dish.Description);
Map(dish => dish.Price);
References(x => x.Category, "CategoryId").Cascade.None();
HasManyToMany(comp => comp.Scroll)
.Table("ComplexDish")
.ParentKeyColumn("DishId")
.ChildKeyColumn("ComplexId").Inverse();
}
}
I use DAO pattern - and when data from front-end come I create needed object
And object save but not whole object only name and description have saved but collection of products doesn't save. I think i forgot some simple thing please help me.
Usually a many-to-many to me represents associations between two separate entities where the entities themselves manage their life cycles.
For example. In your scenario
var firstDish = new Dish();
var secondDish = new Dish();
// 01 -- both dish objects are now attached to the session
session.SaveOrUpdate(firstDish);
session.SaveOrUpdate(secondDish);
var firstComplexObject = new Complex();
firstComplexObject.ScrollOfDish.Add(firstDish);
firstComplexObject.ScrollOfDish.Add(secondDish);
// 02 -- first Complex Object now attached to the session
session.SaveOrUpdate(firstComplextObject);
var secondComplexObject = new Complex();
secondComplexObject.ScrollOfDish.Add(firstDish);
secondComplexObject.ScrollOfDish.Add(secondDish);
// 03 -- second Complex Object now attached to the session
session.SaveOrUpdate(secondComplextObject);
I would avoid the complex Object managing the life cycle of Dish object like
var firstDish = new Dish();
var secondDish = new Dish();
var firstComplexObject = new Complex();
firstComplexObject.ScrollOfDish.Add(firstDish);
firstComplexObject.ScrollOfDish.Add(secondDish);
// the dish object are not attached to session
// hence the NHibernate has to save the entire object graph here!!!!
// 01 -- first Complex Object now attached to the session
session.SaveOrUpdate(firstComplextObject);
var secondComplexObject = new Complex();
secondComplexObject.ScrollOfDish.Add(firstDish);
secondComplexObject.ScrollOfDish.Add(secondDish);
// 02 -- second Complex Object now attached to the session
session.SaveOrUpdate(secondComplextObject);
Also since dishes would certainly be shared between two complex object, it would make sense to not cascade a DELETE from the complex item to the dish.
Hence I would make sure that you DO manage the life cycles separately.
Hope this pushes you in the right direction.

Resources