Variable Space Between lines

You are passing the current interval to your make_geometry method in the spacings.each loop, but the make_geometry does nothing with the interval you passed, it just uses hard-wired values for point1 and point2. And the last line setting constline = @ent.add_cline is pointless, as the variable it assigns is temporary (the argument) and the method returns the last value anyway, whether assigned to something or not.
You should do something with the argument in make_geometry, such as add it to one of the coordinates of the points you create.

So the question is how to get the values from the input to the def method so you can use it to create clines between it?

Your snippet is passing each value of interval to make_geometry in the each block. It arrives in make_geometry(constline) as the value of ‘constline’. So you just need to do something with constline in the body of the method.

This is fundamental Ruby. Maybe you need to study up some more on the basics?

Thanks for the answer.

I tried a lot of different things with this code to get the lines on the given places also add some puts.

But i can’t find what is going wrong because the interval given the right sizes in mm.

Also tried some things with pointx.offset!([1,0,0],(spacings)) but also this type of code doens’t transform it right.

Could someone help with this part?

Thanks

How about trying something like:

def make_geometry( constline  )

point1 = Geom::Point3d.new(constline,0,0)
point2 = Geom::Point3d.new(constline,2000.mm,0)
@ent.add_cline(point1, point2)
end

Why did you think the argument passed to make_geometry would have any effect when your code doesn’t do anything with it (other than pointlessly assign the return from add_cline to it)? As I wrote earlier, you seem confused about basic concepts of Ruby methods.

The offset must use the interval passed as the argument.

Let us say that the object will be copied along the x axis, and that you have already gotten 2 points from the user (@point1, @point2) via an Sketchup::InputPoint instance in your Rubytool *

def make_geometry( interval )
  @point1.offset!(@vec)
  @point2.offset!(@vec)
  @ents.add_cline( @point1, @point2 )
end

model.start_operation("Spaced Geometry")
  spacings.each {|interval|
    # Create a vector for offsetting points along the x axis:
    @vec = Geom::Vector3d::new(interval,0,0)
    # Call a method that uses the interval:
    make_geometry(interval)
  }
model.commit_operation

*: See the example “linetool.rb” in the Example Ruby Scripts extension.


At some time, you’ll need to learn how to do these simple things by yourself.

Have you read any of the free Ruby books listed in my Ruby Learning Resources listing ?

1 Like

Thanks again for the help and it is working :slight_smile:

I know i must learn a lot in Ruby and sometimes is language my biggest problem what makes it harder to understand sometimes.

Going to read the stuff you sent

I actually did not show doing this in the last example, so here is better example that passes the interval and creates the vector object locally inside the make_geometry() method:

def make_geometry( interval )
  # Create a vector for offsetting points along the x axis:
  vec = Geom::Vector3d::new(interval,0,0)
  @point1.offset!(vec)
  @point2.offset!(vec)
  @ents.add_cline( @point1, @point2 )
end

model.start_operation("Spaced Geometry")
  spacings.each {|interval|
    # Call a method that uses the interval:
    make_geometry(interval)
  }
model.commit_operation

Hi,

I have this code now working also with dimension lines.

I use the code to create the dimension lines:

     @offset2=[0, -50, 0]`

```def make_geometry3 ( interval )
      @intermediate=@start2.offset([1,0,0], interval)
      @ent.add_dimension_linear(@start2, @intermediate, @offset2)
      @start2=@intermediate
      @intermediate=@start.offset(@vec, interval)```

<img src="//discourse-cloud-file-uploads.s3.dualstack.us-west-2.amazonaws.com/sketchup/original/3X/6/5/658fd9ea38ad9f7c30237971b5749faec8441b54.jpg" width="690" height="311">

I was trying to do the same thing to create a component or group that uses the variable length but without success.
Can you use the spacings values to create components or groups this way?

Thanks

Yes.


P.S. - When you post code, please put it between lines of triple backticks (with the coding language name on the first line if you know it.)

Like this:

```ruby
# code goes here
```

Hi,

Strange i used the trippel backticks.

But it is possible you say. Do i have to search it in a push pull code, transformation.scaling or set dynamic attributes? I tried all three without the success for now.

Thanks

if you add the word ‘ruby’ as Dan shows you’ll get the appropriate syntax highlighting…

john

I do not know what “this way” is because your example code is incomplete, poorly spaced, and not correctly indented.

I will guess.

If you mean, you wish to create one component, and then insert instances of this component at the spacings, then yes you can do this.

Examples (untested) just for ideas:

def make_component(cname = "New Component Name")
  model = Sketchup.active_model
  cdef  = model.definitions.add(cname)
  cents = cdef.entities
  # Add geometry to cents here
  return cdef
end

def make_geometry( cdef, trans )
  aents = Sketchup.active_model.active_entities
  aents.add_instance( cdef, trans )
end

def do_operation( 
  start_point = Geom::Point3d::new( 0, 0, 0 ),
  op_name = "Spaced Components" 
)
  model.start_operation( op_name )
    # Make the component definition:
    comp_def = make_component("Test Component")
    # Create a transformation set to the start point:
    trans = Geom::Transformation.new( start_point )
    # Make the first component instance:
    make_geometry( comp_def, trans )
    # Make the spaced component instances:
    @spacings.each {|interval|
      # Create a x-axis vector for this interval:
      vec = Geom::Vector3d::new( interval, 0, 0 )
      # Apply this interval vector to the running transform:
      trans = trans * Geom::Transformation::new( vec )
      # Call a method that uses the transformation:
      make_geometry( comp_def, trans )
    }
  model.commit_operation
end

Thanks Dan,

That is what i was searching for :slight_smile: with some little changes it works great. I also added the part that makes the length of the component equal to the variable spacings.
So thanks Dan :slight_smile:

def make_component(cname = "New Component Name")
  model = Sketchup.active_model
  cdef  = model.definitions.add(cname)
  cents = cdef.entities 
  # Add geometry to cents here
    fac = cents.add_face([0,0,0],[0,100.mm,0],[0,100.mm,300.mm],[0,0,300.mm])
    fac.reverse!
    fac.pushpull(100.mm)
  return cdef
end

def make_geometry( cdef, trans )
  aents = Sketchup.active_model.active_entities
  aents.add_instance( cdef, trans )
end

@start_point = Geom::Point3d::new( 0, 0, 0)

@model.start_operation( "C-profiel" )
    # Make the component definition:
    comp_def = make_component("C-profiel")
    # Create a transformation set to the start point:
    trans = Geom::Transformation.new( @start_point )     
      spacings.each {|interval|
      # Create a x-axis vector for this interval:
      vec = Geom::Vector3d::new( interval, 0, 0 )
      # Apply this interval vector to the running transform:
      trans = trans * Geom::Transformation::new( vec )
      # Call a method that uses the transformation:
      t = Geom::Transformation.scaling @start_point, interval/3.937, 1 , 1 
      make_geometry( comp_def, trans*t )
    }
  @model.commit_operation

Hi,

I have a question about this part:

 t = Geom::Transformation.scaling @start_point, interval/3.937, 1 , 1 
 make_geometry( comp_def, trans*t )

first i made a component in the code. But i now want to use one from my c: drive.
but i can’t get the dc updated so the length is correct. See my picture below, i have made an interval from 4000 mm but the dc length is still 100 mm in the component options.

Normaly you can solve this with

dcs = $dc_observers.get_latest_class
dcs.redraw_with_undo(cdef)

But this isn’t working?

You would have to insert the instance, then set the “LenX” attribute in the instance’s “dynamic_attributes” dictionary.

Lastly call the redraw passing the instance reference as the argument (not the definition reference.)

Thanks Dan,

I started to follow this step by step and you make the instance in def make_geometry so there should be the “LenX” attribute. but where should the redraw be placed? after the spacings.each {|interval| part? because that didn’t worked for me. This is the very last thing i need to know about this code but i can’t find were it goes wrong.

def make_component(cname = "New Component Name")
  model = Sketchup.active_model
  definitions = model.definitions
  cdef = definitions.load ( "Z:/Algemeen 2016/Systeemvloeren/Tekeningen/Sketchup/C-profiel 3.skp" ) 
  return cdef
end

def make_geometry( cdef, trans )
  aents = Sketchup.active_model.active_entities
  aents.add_instance( cdef, trans )
  aents.set_attribute( 'dynamic_attributes', '_lenx_formula', "100" )
end

@start_point = Geom::Point3d::new( 0, 0, 0)

@model.start_operation( "C-profiel" )
    # Make the component definition:
    comp_def = make_component("C-profiel")
    # Create a transformation set to the start point:
    trans = Geom::Transformation.new( @start_point )     
    
    spacings.each {|interval|
    # Create a x-axis vector for this interval:
      vec = Geom::Vector3d::new( interval, 0, 0 )
    # Apply this interval vector to the running transform:
      trans = trans * Geom::Transformation::new( vec )
    # Call a method that uses the transformation:
      t = Geom::Transformation.scaling @start_point, interval/3.937, 1 , 1 
      make_geometry( comp_def, trans*t )
    }

   dcs = $dc_observers.get_latest_class
   dcs.redraw_with_undo(aents)

  @model.commit_operation

These lines need to be inside the method where you create the instance, AND where the reference aents is valid. References created inside the scope of a method, do not exist outside that method. They are destroyed when the call to that method ends, and recreated when the method is called again.


BUT, if all of the instances are going to be the same, then you can change the definition’s default LenX, instead of changing every instance.

Ok,

Maybe there is an easier way to this but i never done this with methodes.

In the picture below an example from what i need. The C-profiel is white and uses the interval. So the instance is the same only the LenX is variable. In this picture is the first one 4.000 mm and the second one 5.000 mm. So this length should be updated so i can use them to generate a report.

You are the programmer. You decide what to do.

Isn’t it obvious that you would need to pass the interval into the make_geometry() method so you could use it to set the instance’s length or use the interval to apply a scaling to the instance ?

You’ll have to do one or the other. It is up to you.