Thanks to DevTech engineer Vladimir Ananyev for providing this post and great example.
Recently we were asked if the Inventor API could help by suppressing elements of holes in a rectangular pattern which are not completely inside a user-defined boundary.
The algorithm needs to suppress holes that have centers located outside the boundary at a distance greater than the hole radius from the boundary. The boundary could be complex geometry and the most difficult problem was to determine if the hole was completely inside or outside the boundary. This problem was solved by using Inventor API objects involved in the creation of profiles for solid geometry.
In the screenshots below you see a sketch and the extrusion that is created using the profile created with the AddForSolid() method.
Dim oProfile As Profile _
= oSketch.Profiles.AddForSolid(True)
The result is shown in Fig. 2.
If a circular profile path crosses the ellipse (boundary) or is located completely outside then it adds material to the solid body. Otherwise it subtracts material.
Figures 3 and 4 show that this rule works for profile paths of any other geometry as well.
This powerful built-in topology analyzer of the AddForSolid method you can be used to easily identify pattern elements that are completely inside the specified boundary. (Fortunately there are not any restrictions on the geometry of the profile paths).
To demonstrate this approach I used an iLogic rule. (Any language that can access the Inventor API could have been used too). In figure 5 you see the full rectangular pattern. After the rule is run, the holes outside of the boundary are suppressed. (figure 6)
The steps are as follows.
1. The Main function projects the boundary geometry from the planar sketch “Boundary” and all the elements of the holes pattern into the created on-the-fly transient planar sketch. (For simplicity the rule works with the first rectangular pattern in its parent part document).
2. It then calls the AddForSolid method to create a profile object based on the combined projected geometry in the transient sketch.
3. The rule analyses every profile path in the profile object. If the path represents a projected hole’s pattern element and its property AddsMaterial returns True, then the corresponding pattern element is suppressed. The search for FeaturePatternElement is based on the reference to the projected sketch circle is performed by the function GetEltByGreenCircle.
Note: The parent hole feature cannot be suppressed otherwise all the pattern will be suppressed as well, that is why our code ignores the parent feature.
An Inventor part file with the iLogic rule can be downloaded here.
Here are the two iLogic rules:
Sub Main()
Dim oDoc As PartDocument =
TryCast(ThisDoc.Document, PartDocument)
If oDoc Is Nothing Then
MessageBox.Show _
("This rule works with part documents only.",
"iLogic Rule", _
MessageBoxButtons.OK,
MessageBoxIcon.Warning)
Exit Sub
End If
Dim oDef As PartComponentDefinition =
oDoc.ComponentDefinition
'this rule works with only one rect. pattern only
'provided directly by item number
Dim oPattern As RectangularPatternFeature =
oDef.Features.RectangularPatternFeatures.Item(1)
'restore all pattern elements in order to
'get access to their faces
For Each oElt As FeaturePatternElement _
In oPattern.PatternElements
If oElt.Suppressed Then
oElt.Suppressed = False
End If
Next
oDoc.Update()
ThisApplication.ActiveView.Update()
Beep()
Dim oBoundarySketch As PlanarSketch =
oDef.Sketches.Item("Boundary")
'temporary sketch for profile
Dim oSketch As PlanarSketch =
oDef.Sketches.Add _
(oBoundarySketch.PlanarEntity, False)
oSketch.Visible = False
'project boundary
For Each oE As SketchEntity _
In oBoundarySketch.SketchEntities
Call oSketch.AddByProjectingEntity(oE)
Next
'project parent hole
Dim oHole As HoleFeature =
TryCast(oPattern.ParentFeatures.Item(1),
HoleFeature)
If oHole Is Nothing Then
MessageBox.Show _
("This rule works with hole feature pattern only.",
"iLogic Rule", _
MessageBoxButtons.OK, MessageBoxIcon.Warning)
Exit Sub
End If
Dim oEdge As Edge =
oHole.SideFaces.Item(1).Edges.Item(1)
Call oSketch.AddByProjectingEntity(oEdge)
'project holes pattern
For Each oElt As FeaturePatternElement _
In oPattern.PatternElements
If oElt.Faces.Count > 0 Then
oEdge = oElt.Faces.Item(1).Edges.Item(1)
Call oSketch.AddByProjectingEntity(oEdge)
End If
Next
' Create a profile.
Dim oProfile As Profile =
oSketch.Profiles.AddForSolid(True)
For Each oPath As ProfilePath In oProfile
If oPath.Count = 1 Then
Dim oPE As ProfileEntity = oPath.Item(1)
If oPE.CurveType =
Curve2dTypeEnum.kCircleCurve2d Then
Dim oSkE As SketchEntity =
oPE.SketchEntity
Dim oGreenCircle As SketchCircle =
CType(oSkE, SketchCircle)
Dim oFPE As FeaturePatternElement =
GetEltByGreenCircle(oGreenCircle)
If oFPE IsNot Nothing Then
If oPath.AddsMaterial = True Then
'should be suppressed
oFPE.Suppressed = True
End If
End If
End If
End If
Next
'delete temporary sketch
oSketch.Delete()
oDoc.Update()
Beep()
End Sub
Function GetEltByGreenCircle( _
ByRef oGreenCircle As SketchCircle) _
As FeaturePatternElement
'returns FPE corresponding to the
'given SketchCircle object
If oGreenCircle Is Nothing Then Return Nothing
Dim oEdge As Edge
Try
oEdge = CType(oGreenCircle. _
ReferencedEntity, Edges).Item(1)
Catch ex As Exception
Return Nothing
End Try
Dim oFace As Face
If oEdge.Faces.Item(1).SurfaceType =
SurfaceTypeEnum.kCylinderSurface Then
oFace = oEdge.Faces.Item(1)
Else
oFace = oEdge.Faces.Item(2)
End If
If oFace.CreatedByFeature.Type =
ObjectTypeEnum.kHoleFeatureObject Then
Return Nothing
End If
Dim lKey As Long = oFace.TransientKey
Dim oPattern As RectangularPatternFeature _
= CType(oFace.CreatedByFeature, _
RectangularPatternFeature)
For Each oElt As FeaturePatternElement
In oPattern.PatternElements
If oElt.Faces.Count > 0 Then
If lKey = oElt.Faces.Item(1). _
TransientKey Then
Return oElt
End If
End If
Next
Return Nothing
End Function 'GetEltByGreenCircle
(Thanks! to Vladimir)
-Wayne