I'm trying to use the Graph.pm module but all the examples I saw are keeping simple basic scalars as nodes. I'm trying to keep instances of three different classes as nodes in that graph. Consider:
sub new {
my ($class,$node_name) = #_;
my $self = {
"name" => $node_name,
# More fields
};
bless $self, $class;
return $self;
}
Now I can do something like:
$g->add_vertex(new DNode("/"));
where DNode is the constructor of one of the three classes. But how can I can look for that node? For example, I have:
$g->add_vertex(new DNode("/"));
$g->add_vertex(new DNode("/a"));
$g->add_vertex(new DNode("/a/b"));
my $node = $g->get_vertex("/a/b");
There is no get_vertex. I thought that add_vertex_by_id can be helpful here:
$g->add_vertex_by_id(new DNode("/"),"/");
$g->add_vertex_by_id(new DNode("/a"),"/a");
$g->add_vertex_by_id(new DNode("/a/b"),"/a/b");
But there is no get_vertex_by_id method. How can I do the lookup?
It's not 100% clear what you're really trying to achieve. I can try to explain the things you did ask about (I'm the module's current maintainer).
The Graph module is about things, and connections between things. The usual approach, which I think will work for you here, is to identify "things" (vertices) by string names, such as "/" or "/a", and set an attribute (e.g. object) as the Perl object. You can instead have the vertices identified by actual Perl objects, using refvertexed.
Once you've added a vertex, like this:
$g = Graph->new;
$g->set_vertex_attribute('/a', object => $node_class->new('/a')); # no need to separately add vertex
You can look it up:
$bool = $g->has_vertex('/a');
$obj = $g->get_vertex_attribute('/a', 'object'); # safely returns undef if no such vertex, or attribute not set
The by_id methods are part of Multiedges, Multivertices, Multigraphs, where you'd have several (or "multi") "aspects" of the same vertex, each identified by an ID. I don't think that's what you want here.
If this doesn't solve your problem, you'd need to explain your problem more/better :-)
I recently found out about TryGetComponent and did some research on it. I found out that main difference is that TryGetComponent "does not allocate in the Editor when the requested component does not exist". I don't really know what that means since I am still new to Unity and why would someone request component that does not exist in the first place, so could somebody explain if I should stop using GetComponent, and if so why?
Thanks in advance.
There might be some reasons to use GetComponent without being sure if this component exists. In this case it is necessary to check if the component is actually there or not.
For example, you have an array of game objects (in this case it is RaycastHit2D array and was aquired from Physics2D.GetRayIntersectionAll method). You need to invoke a specific method from every game object that contains a specific component. You can use GetComponent and check if it equals null or not.
RaycastHit2D[] ray = Physics2D.GetRayIntersectionAll(_mainCamera.ScreenPointToRay(Input.mousePosition));
foreach (RaycastHit2D item in ray)
{
var myClass = item.transform.GetComponent<MyClass>();
if (myClass != null )
{
myClass.MyMethod();
}
}
Or you can use TryGetComponent. In this case you do not need to use GetComponent multiple times or create an additional variable. And the code looks cleaner.
RaycastHit2D[] ray = Physics2D.GetRayIntersectionAll(_mainCamera.ScreenPointToRay(Input.mousePosition));
foreach (RaycastHit2D item in ray)
{
if (item.transform.TryGetComponent(out MyClass myClass))
{
myClass.MyMethod();
}
}
TryGetComponent seems to be more useful in some particular cases, but not always.
Is there a way to make difference directly from root? I want to do something like this:
difference(){
root();
cube();
}
instead of this:
difference(){
union(){
object1();
object2();
.
.
objectN();
}
cube();
}
You are already on the there. You just need to define root() and cube() as modules like so:
difference(){
root();
cube();
}
module root(){
object1();
object2();
...
}
module cube(){
//some cube definition
}
In the background OpenSCAD will secretly create a union() around every module for you, just as if you wrote:
module xyz(){
union(){
//objects
}
}
So in this example an object root() is created and cube() will be subtracted from this object. By using the module definition you keep your code just as modular as you ask for.
You may also want to have a look at the official docu and cheat sheet here.
difference() module subtracts all other children from the first one. In first snippet, first child is root(), in second first child is union(), and in both cube is subtracted.
I know that when I use for it creates a group of the generated children.
I created a module called grid like so:
module grid(x0,y0,dx,dy,nx,ny) {
for (x=[0:1:nx-1]) {
for(y=[0:1:ny-1]) {
i=x*nx+y;
echo(i);
translate([x0+x*dx,y0+y*dy,0]) children(i);
}
}
}
which when used like this:
grid(-50,-50,25,25,5,5) {
cube([10,10,10],center=true);
cube([10,10,10],center=true);
cube([10,10,10],center=true);
cube([10,10,10],center=true);
//.. continue to create 25 cubes total
}
arranges the cubes in a nice grid.
however my original hope and intention was to use it like this:
grid(-50,-50,25,25,5,5) {
for(i=[0:1:24]) {
cube([10,10,10],center=true);
}
}
Which fails because the for operator returns a group and not a set of children.
Why does the for add a group to begin with? (also leading to the need for intersection_for)
And is there a way for my Grid operator module to handle the children of the group?
I personally hope for the grouping/union for elements within a for() to become optional at some time.
If you don't mind compiling OpenSCAD from source, you could try it already today.
There is an ongoing issue Lazy union (aka. no implicit union)
and a patch here Make for() UNION optional
Just updated my knowledge of OpenSCAD, there is a better solution:
module nice_cube()
{
translate([0,0,$height/2]) cube([9,9,$height], center = true);
}
module nice_cylinder()
{
translate([0,0,$height/2]) cylinder(d=10,h=$height, center = true);
}
module nice_text()
{
linear_extrude(height=$height, center=false) text(str($height), size=5);
}
module nice_grid()
{
for(i=[0:9], j=[0:9])
{
$height=(i+1)*(j+1);
x=10*i;
y=10*j;
translate([x,y,0]) children();
/* let($height=(i+1)*(j+1)) {children();} */
}
}
nice_grid() nice_cube();
translate([0,-110,0]) nice_grid() nice_text();
translate([-110,0,0]) nice_grid() nice_cylinder();
The trick here is to control the shape produced by module by special variables (starting with $) those can be used like in example, commented line using let() requires development version of openscad.
I guess You want this:
for(x=[...], y=[...]) {
translate([x,y,0]) children();
}
Note, that you need only one for statement to loop through both x and y values.
What I have understood from your comment is, that you want your objects in the nodes of the grids to be parametric, and parameter depends on index. This requirement was not mentioned in the original question. In this case, solution depends on your problem context, I guess. The two possibilities I see are:
module grid_of_parametric_modules(other_param)
{
for(i=[0:24])
{
x=_x(i);
y=_y(i);
translate([x,y,0]) parametric_module(i_param(i), other_param);
}
}
However this may not be suitable, especially if You are going to add new shapes to your grid in future. Then you can probably do it like:
function grid_pos(i) = [_x(i), _y(i), 0];
....
for(i=[0:24])
translate(grid_pos(i)) parametric_module(i);
I have a table with a series of rows. I want to change them into divs, but maintain (somehow) their positional information. At the moment, this is what I'm doing:
$("./tr[1]") {
add_class("mw_old_row_1")
}
$("./tr[2]") {
add_class("mw_old_row_2")
}
$("./tr") {
name("div")
}
But this isn't ideal because:
It's super-repetitive
I don't know how many rows there are
Is there a way to take the child number and include that in the class I'm assigning?
Yup, you want to make use of the index() function. Below is the example you wrote reworked using index():
$("./tr") {
add_class("mw_old_row_" + index())
name("div")
}
Below is a link with the following example in tritium tester: http://tester.tritium.io/775895b154e8e2ce99e100967299c10d73dbeb91