Module: Autocad::ElementTrait

Included in:
Element
Defined in:
lib/autocad/element.rb

Instance Method Summary collapse

Instance Method Details

#autocad_typeObject

Get the AutoCAD object type name



304
305
306
# File 'lib/autocad/element.rb', line 304

def autocad_type
  ole_obj.ObjectName
end

#block_reference?Boolean

Check if this element is a block reference

Returns:

  • (Boolean)


72
73
74
# File 'lib/autocad/element.rb', line 72

def block_reference?
  false
end

#boundsObject

def bounds

minpoint = WIN32OLE::Variant.new([0.0, 0.0, 0.0], WIN32OLE::VARIANT::VT_ARRAY | WIN32OLE::VARIANT::VT_R8)
maxpoint = WIN32OLE::Variant.new([0.0, 0.0, 0.0], WIN32OLE::VARIANT::VT_ARRAY | WIN32OLE::VARIANT::VT_R8)

ole_obj.GetBoundingBox(minpoint, maxpoint)

min_pt = Point3d.new(minpoint[0], minpoint[1], minpoint[2])
max_pt = Point3d.new(maxpoint[0], maxpoint[1], maxpoint[2])

BoundingBox.from_min_max(min_pt, max_pt)

rescue => e

raise Autocad::Error.new("Error getting bounds: #{e.message}")

end



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/autocad/element.rb', line 90

def bounds
  # For testing purposes, check if we're in a test environment
  # This is a workaround for the test environment where we don't have actual OLE objects

  begin
    if ole_obj.ole_respond_to?(:GetBoundingBox)
      # Create VARIANT objects for output parameters
      minpoint = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_VARIANT | WIN32OLE::VARIANT::VT_BYREF)
      maxpoint = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_VARIANT | WIN32OLE::VARIANT::VT_BYREF)
      # Last resort - try GetBoundingBox if available


      # Get the bounding box coordinates
      ole_obj.GetBoundingBox(minpoint, maxpoint)


      # Convert the VARIANT arrays to Point3d objects
      min_pt = Point3d.new(minpoint.value[0], minpoint.value[1], minpoint.value[2])
      max_pt = Point3d.new(maxpoint.value[0], maxpoint.value[1], maxpoint.value[2])


      BoundingBox.from_min_max(min_pt, max_pt)
    # Try different approaches based on object type
    elsif ole_obj.ole_respond_to?(:Coordinates)
      # For objects like lines that have Coordinates property
      coords = ole_obj.Coordinates

      # Find min and max values
      x_values = []
      y_values = []
      z_values = []

      (0...coords.size).step(3) do |i|
        x_values << coords[i]
        y_values << coords[i + 1]
        z_values << coords[i + 2] if i + 2 < coords.size
      end
      puts ole_obj.ObjectName
      binding.irb

      min_pt = Point3d.new(x_values.min, y_values.min, z_values.min || 0)
      max_pt = Point3d.new(x_values.max, y_values.max, z_values.max || 0)
      binding.irb

      BoundingBox.from_min_max(min_pt, max_pt)
    elsif ole_obj.ole_respond_to?(:Center) && ole_obj.respond_to?(:Radius)
      # For circles
      center = Point3d.new(ole_obj.Center)
      radius = ole_obj.Radius

      min_pt = Point3d.new(center.x - radius, center.y - radius, center.z)
      max_pt = Point3d.new(center.x + radius, center.y + radius, center.z)
      binding.irb

      BoundingBox.from_min_max(min_pt, max_pt)
    elsif ole_obj.ole_respond_to?(:StartPoint) && ole_obj.respond_to?(:EndPoint)
      # For lines with start and end points
      start_pt = Point3d.new(ole_obj.StartPoint)
      end_pt = Point3d.new(ole_obj.EndPoint)
      puts ole_obj.ObjectName

      binding.irb

      min_x = [start_pt.x, end_pt.x].min
      min_y = [start_pt.y, end_pt.y].min
      min_z = [start_pt.z, end_pt.z].min

      max_x = [start_pt.x, end_pt.x].max
      max_y = [start_pt.y, end_pt.y].max
      max_z = [start_pt.z, end_pt.z].max

      min_pt = Point3d.new(min_x, min_y, min_z)
      max_pt = Point3d.new(max_x, max_y, max_z)

      binding.irb

      BoundingBox.from_min_max(min_pt, max_pt)
    else
      binding.irb
      nil
      # If we can't determine bounds, create a default bounding box
      # This is better than raising an error in many cases
    end
  rescue => e
    puts e.message
    binding.irb
    load "win32ole_helper"
    ole_obj.extend WIN32OLE::Helper
    load "autocad\element.rb"
    retry
    # If all methods fail, return an empty bounding box instead of raising an error
    # This makes the code more robust when dealing with various object types
    nil
  end
end

#cell?Boolean

Check if this element is a cell

Returns:

  • (Boolean)


226
227
228
# File 'lib/autocad/element.rb', line 226

def cell?
  ole_obj.Type == ::ACAD::MsdElementTypeCellHeader
end

#def(autocad_id) ⇒ Object

Get the AutoCAD object ID



242
243
244
245
246
# File 'lib/autocad/element.rb', line 242

def autocad_id
  @ole_obj.ObjectId
rescue
  nil
end

#drawingObject

Get the parent drawing of this element



60
61
62
# File 'lib/autocad/element.rb', line 60

def drawing
  app.current_drawing
end

#explodeObject

Explode this element into its component parts



201
202
203
204
205
206
207
208
209
210
# File 'lib/autocad/element.rb', line 201

def explode
  return enum_for(__callee__) unless block_given?

  ole = ole_obj.explode
  ole.each do |ole|
    yield app.wrap(ole)
  end
rescue => e
  binding.irb
end

#graphical?Boolean

Check if this element is graphical

Returns:

  • (Boolean)


262
263
264
# File 'lib/autocad/element.rb', line 262

def graphical?
  ole_obj.IsGraphical
end

#has_tags?Boolean

Check if this element has any tags

Returns:

  • (Boolean)


214
215
216
# File 'lib/autocad/element.rb', line 214

def has_tags?
  ole_obj.HasAnyTags
end

#highlight(flag = true) ⇒ Object

Highlight this element in the drawing



233
234
235
236
# File 'lib/autocad/element.rb', line 233

def highlight(flag = true)
  ole_obj.Highlight(flag)
  ole_obj.Update
end

#id_from_record(id) ⇒ Object

Convert record ID to element ID



289
290
291
292
293
294
# File 'lib/autocad/element.rb', line 289

def id_from_record(id)
  return unless id.instance_of?(WIN32OLE_RECORD)
  return id.Low if id.Low > id.High

  id.High
end

#inspectObject

Get string representation of this element



268
269
270
271
272
273
274
# File 'lib/autocad/element.rb', line 268

def inspect
  "<#{self.class} -name: #{begin
    name
  rescue
    nil
  end}> #{acad_type}"
end

#line?Boolean

Check if this element is a line

Returns:

  • (Boolean)


256
257
258
# File 'lib/autocad/element.rb', line 256

def line?
  ole_obj.ObjectName == "AcdbLine"
end

#modelObject

Get the model containing this element



310
311
312
# File 'lib/autocad/element.rb', line 310

def model
  Model.new(app, app.current_drawing, ole_obj.ModelReference)
end

#parentObject

Get the parent element



278
279
280
281
282
283
284
# File 'lib/autocad/element.rb', line 278

def parent
  parent_id = ole_obj.ParentID
  return nil unless parent_id

  id = id_from_record(parent_id)
  app.active_design_file.find_by_id(id)
end

#pviewport?Boolean

Check if this element is a paper space viewport

Returns:

  • (Boolean)


66
67
68
# File 'lib/autocad/element.rb', line 66

def pviewport?
  false
end

#selectObject

Select this element in the drawing



298
299
300
# File 'lib/autocad/element.rb', line 298

def select
  app.active_model_reference.select_element(self)
end

#text?Boolean

def text? Check if this element is a text object

Returns:

  • (Boolean)


194
195
196
# File 'lib/autocad/element.rb', line 194

def text?
  ole_obj.ole_type == "IAcadText"
end

#to_oleObject

Get the underlying OLE object



220
221
222
# File 'lib/autocad/element.rb', line 220

def to_ole
  ole_obj
end

#visible?Boolean

Check if this element is visible

Returns:

  • (Boolean)


250
251
252
# File 'lib/autocad/element.rb', line 250

def visible?
  @ole_obj.Visible
end