Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Surface Evaluator does not work as expected

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
ga42bon
1010 Views, 14 Replies

Surface Evaluator does not work as expected

Hello everyone,

I am working on a programm to get the center point of surfaces. To calculate the center point, I try to get the data of the surface, i.e. the corner points. I tried to get the corner points as MinPoints and MaxPoints of the SurfaceEvaluator and its properties 'ParamRangeRect' and 'RangeBox'. Right now, this is not working.

It seems that the properties 'ParamRangeRect' and 'RangeBox' both are not getting the actual surface. The results of using those properties are always different than the 'real' face. I have created a sketch with the MinPoints and MaxPoints to see the contours of the properties (see screenshots attached).

Is there something I am missing in using ParamRangeRect oder RangeBox?

Is there another way to get the 3d coordinates of the surface center point?

 

Down below you can see my Sub to get the center of a surface. The input face is selected before.

This is the example for the property 'RangeBox':

 

Private Sub f_getCenter(InputFace As Face) As SketchPoint

   Dim eval As SurfaceEvaluator = InputFace.Evaluator

   ' Get the center of the parametric range.
   Dim center(1) As Double

   ' Get RangeBox for Min and Max Values
   Dim oRange As Box = eval.RangeBox

   ' Get center of the RangeBox
   center(0) = (oRange.MaxPoint.Z + oRange.MinPoint.Z) / 2  
   center(1) = (oRange.MaxPoint.Y + oRange.MinPoint.Y) / 2   

   Dim oAsmCompDef As AssemblyComponentDefinition = g_inventorApplication_
                                       .ActiveDocument.ComponentDefinition
   Dim oTG As TransientGeometry = g_inventorApplication.TransientGeometry
   Dim oSketch As PlanarSketch = oAsmCompDef.Sketches.Add(InputFace)
   
   ' Draw sketch point of center
   Dim oPoint As SketchPoint = oSketch.SketchPoints._
                           Add(oTG.CreatePoint2d(center(0), center(1)), True)

   ' ----------- TEST for min and max points of surface --------------
   Dim oPoint1 As SketchPoint = _ oSketch.SketchPoints._
           Add(oTG.CreatePoint2d(oRange.MinPoint.Z, oRange.MinPoint.Y), True)
   Dim oPoint2 As SketchPoint = oSketch.SketchPoints._
           Add(oTG.CreatePoint2d(oRange.MaxPoint.Z, oRange.MinPoint.Y), True)
   Dim oPoint3 As SketchPoint = oSketch.SketchPoints._
           Add(oTG.CreatePoint2d(oRange.MinPoint.Z, oRange.MaxPoint.Y), True)
   Dim oPoint4 As SketchPoint = oSketch.SketchPoints._
           Add(oTG.CreatePoint2d(oRange.MaxPoint.Z, oRange.MaxPoint.Y), True)
   ' -------------------------------

   Return oPoint

End Function

 

 The Sub with the property 'ParamRangeRect' only has a few changes compared to the one above.

 

Thank you for your help.

Sebastian

14 REPLIES 14
Message 2 of 15
Michael.Navara
in reply to: ga42bon

This looks you don't use faces and its proxies (in assembly context) correctly.

Test your code in part environment first and then go to assembly and try to use FaceProxy instead of Face object. 

Message 3 of 15
Ralf_Krieg
in reply to: ga42bon

Hello

 

In addition to @Michael.Navara 's comment

The point you get is not the geometric center of the face. If you expect the geometric center, your calculation will almost work for rectangular faces and circles. Any unsymetric polygon will not work. The RangeBox is also defined as encloses all geometry, but this means not the rectangle can not be greater in one or both dimensions.

 

 


R. Krieg
RKW Solutions GmbH
www.rkw-solutions.com
Message 4 of 15
ga42bon
in reply to: Michael.Navara

Thanks for the quick answer!

 

I tried it following three concepts:

1. Test code with FaceProxy in PartDocument

2. Test code with Face in PartDocument

3. Test code with FaceProxy in AssemblyDocument

4. Test code with Face and FaceProxy in AsseblyDocument while accessing the PartComponent and creating a sketch there

 

Results:

1. Error: Could not set selected face as FaceProxy

2. Same center, MinPoints and MaxPoints with ParamRangeRect as before

3. Same center, MinPoints and MaxPoints with ParamRangeRect as before

4. Error: Could not create Sketch with Face and FaceProxy as Input

(Note: Screenshots are attached for results 1-3. Sorry for the german language in the error message of screenshot 1.)

 

Code Sample of my PartDocument test with Face Proxy:

 

Private Sub f_getRealCenter(InputFace As Face) As SketchPoint

   Dim eval As SurfaceEvaluator = InputFace.Evaluator

   ' Get the center of the parametric range.
   Dim center(1) As Double

   ' Get RangeBox for Min and Max Values
   Dim oRange As Box = eval.RangeBox

   ' Get center of the RangeBox
   center(0) = (oRange.MaxPoint.Z + oRange.MinPoint.Z) / 2  
   center(1) = (oRange.MaxPoint.Y + oRange.MinPoint.Y) / 2   

   Dim oAsmCompDef As AssemblyComponentDefinition = g_inventorApplication_
                                       .ActiveDocument.ComponentDefinition
   Dim oTG As TransientGeometry = g_inventorApplication.TransientGeometry
   Dim oSketch As PlanarSketch = oAsmCompDef.Sketches.Add(InputFace)
   
   ' Draw sketch point of center
   Dim oPoint As SketchPoint = oSketch.SketchPoints._
                           Add(oTG.CreatePoint2d(center(0), center(1)), True)

   ' ----------- TEST for min and max points of surface --------------
   Dim oPoint1 As SketchPoint = _ oSketch.SketchPoints._
           Add(oTG.CreatePoint2d(oRange.MinPoint.Z, oRange.MinPoint.Y), True)
   Dim oPoint2 As SketchPoint = oSketch.SketchPoints._
           Add(oTG.CreatePoint2d(oRange.MaxPoint.Z, oRange.MinPoint.Y), True)
   Dim oPoint3 As SketchPoint = oSketch.SketchPoints._
           Add(oTG.CreatePoint2d(oRange.MinPoint.Z, oRange.MaxPoint.Y), True)
   Dim oPoint4 As SketchPoint = oSketch.SketchPoints._
           Add(oTG.CreatePoint2d(oRange.MaxPoint.Z, oRange.MaxPoint.Y), True)
   ' -------------------------------

   Return oPoint

End Sub


' Test Sub
Private Sub m_mainSub

   ' ------------- TEST -------------
   Dim oFaceOriginal As Face = g_inventorApplication.CommandManager._
                              Pick(SelectionFilterEnum.kPartFaceFilter, _
                              "Select the gripping plane of the gripper jaw")
    Dim oFace As FaceProxy = oFaceOriginal
    Dim oGrippingPlaneCenter As SketchPoint = f_getRealCenter(oFace)

End Sub

 

 

Code sample of concept 4:

 

' Select the conductor as occurence.
Dim oOcc1 As ComponentOccurrence = oAsmCompDef.Occurrences.Item(1)

' Start edit mode
oOcc1.Edit()

' Access the part document component definition
Dim oPartCompDef As PartComponentDefinition = oOcc1.Definition

' Create a new sketch
Dim oSketch As PlanarSketch = oPartCompDef.Sketches.Add(InputFace)
oSketch.Edit()

'' Insert sketch point as test
Dim oPoint As SketchPoint = oSketch.SketchPoints._
                          Add(oTG.CreatePoint2d(center(0), center(1)), True)

' Exit the sketch mode and the part document mode
oSketch.ExitEdit()
oOcc1.ExitEdit(ExitTypeEnum.kExitToPrevious)

 

 

Message 5 of 15
ga42bon
in reply to: Ralf_Krieg

Thank you for the feedback!

 

Is there a way to get the geometric center of any polygon (easily)?

Message 6 of 15
Ralf_Krieg
in reply to: ga42bon

Hello

 

Don't know if this is an easy way, but seems to work. Start the rule in your assembly and pick the part face you need.

 

Private Sub main
	
Dim oApp As Inventor.Application= ThisApplication
Dim oAssDoc As AssemblyDocument= oApp.ActiveDocument
Dim oFaceProxy As FaceProxy = oApp.CommandManager.Pick(kPartFaceFilter, "Pick a face")
Dim oPoint As Point=Nothing

Dim oTrans As Transaction = oApp.TransactionManager.StartTransaction(oAssDoc, "Center of face")
Try
	Dim oSketch As PlanarSketch = oAssDoc.ComponentDefinition.Sketches.Add(oFaceProxy, True)
	Dim oEdge As Edge
	For Each oEdge In oFaceProxy.Edges
    	Call oSketch.AddByProjectingEntity(oEdge)
	Next

	Dim oProfile As Profile = oSketch.Profiles.AddForSolid
	Dim oRProps As RegionProperties = oProfile.RegionProperties
	Dim oPoint2D As Point2d= oApp.TransientGeometry.CreatePoint2d(oRProps.Centroid.X, oRProps.Centroid.Y)

	oPoint = oSketch.SketchToModelSpace(oPoint2D)
Catch ex As Exception
	MsgBox(ex.message)
Finally
	oTrans.Abort
End Try

If oPoint IsNot Nothing Then
	Dim oWP As WorkPoint = oAssDoc.ComponentDefinition.WorkPoints.AddFixed(oPoint)
End If

End Sub

 


R. Krieg
RKW Solutions GmbH
www.rkw-solutions.com
Message 7 of 15
WCrihfield
in reply to: ga42bon

Hi @ga42bon.  Just another similar tool to take note of... If you don't mind ending up with a WorkPoint, instead of a SketchPoint, the WorkPoints.AddAtCentroid() method is a pretty powerful/useful tool in similar situations.  You can give it the outside edges of the face from the Face.EdgeLoops collection.  However, this might not work in an assembly.  Just a thought.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 8 of 15
J-Camper
in reply to: ga42bon

@ga42bon,

 

Here is another approach.  You can use the Part/Assembly ComponentDefintion to create geometry intent, and specify a PlanarFaceCenterPointIntent.  Then just get the Point from the intent. It works like on most planar faces, basically works on any face that give a CenterPoint vertex when selecting a face for an AssemblyJoint.  I added a condition to use a region centroid if the GeometryIntent process Fails.  This example can run in a Part or assembly environment:

Dim blankDef As ComponentDefinition = TryCast(ThisApplication.ActiveDocument.ComponentDefinition, AssemblyComponentDefinition)
If IsNothing(blankDef) Then blankDef = TryCast(ThisApplication.ActiveDocument.ComponentDefinition, PartComponentDefinition)
If IsNothing(blankDef) Then Exit Sub

Dim PickFace As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Select a Planar Face")
If IsNothing(PickFace) Then Exit Sub ' If nothing gets selected then we're done

If PickFace.SurfaceType = SurfaceTypeEnum.kPlaneSurface
	Try  'This is Faster for simple faces
		Dim CenterPoint As Point = blankDef.CreateGeometryIntent(PickFace, PointIntentEnum.kPlanarFaceCenterPointIntent).Point
		
		If blankDef.Type = ObjectTypeEnum.kAssemblyComponentDefinitionObject
			CenterPoint.TransformBy(PickFace.ContainingOccurrence.Transformation)
		End If
		
		blankDef.WorkPoints.AddFixed(CenterPoint)
	Catch 'This is more robust, but slow. If you don't get centerpoint option during Joint Face Selecetion, then the previous fails
		Logger.Debug("Failed PlanarFaceCenterPointIntent")
		
		Dim tempSK As PlanarSketch = blankDef.Sketches.Add(PickFace)
		For Each ed As Edge In PickFace.Edges
			tempSK.AddByProjectingEntity(ed).Construction = False
		Next
		Dim tempProf As Profile = tempSK.Profiles.AddForSurface
		Dim SKpoint As SketchPoint =tempSK.SketchPoints.Add(tempProf.RegionProperties.Centroid)
		Dim ModelPoint As Point = SKpoint.Geometry3d
		tempSK.Delete()

		blankDef.WorkPoints.AddFixed(ModelPoint)
	End Try
Else
	Logger.Debug("Only Processing Planar Faces right now")
End If

 

Let me know if you have any questions or if this is not working as intended.

 

Message 9 of 15
ga42bon
in reply to: ga42bon

Thank you both @Ralf_Krieg and @J-Camper !

Both code samples work perfectly and do the job to get the center of the selected faces!

Message 10 of 15
ga42bon
in reply to: ga42bon

Hi @Ralf_Krieg and @J-Camper 

I have a follow-up question to my problem:

Is there a way to use your code samples also for slightly curved faces?

 

An Example is attached in Screenshot 1.

Message 11 of 15
Ralf_Krieg
in reply to: ga42bon

Hello

 

No, cause the base of both codes is a planar face. I did not found any information on how to  calculate a geometric center or a center of gravity for a curved face. Maybe there's a way, but I don't think it would be easy.

What do you do with the center point afterwards? Maybe there'S an alternative way.


R. Krieg
RKW Solutions GmbH
www.rkw-solutions.com
Message 12 of 15
ga42bon
in reply to: Ralf_Krieg

Hello @Ralf_Krieg,

 

I already had the feeling of this being a more complex problem.

 

My overall task is to align the faces of two parts onto each other in an assembly. I attached two videos to this message to show how my code is working for planar faces and how it also should be for slightly curved faces.

Before using the center point code sample, I already rotated the face of the object to realign the normals of both selected faces. The first video shows the alignment for faces where a rotation is not neccessary. The second video shows the alignment of the faces with a needed rotation.

With the code sample of getting the center point, I get the 3D geometry of those work points and calculate the necessary translation to the opposing center point.

Following this overall task of aligning the two objects, I will check for possible collisions while slightly translating the left body in x-,y- and z-direction to simulate uncertainties of moving this object with a robot arm.

 

I hope this little explanation helps to understand my task and my problem. I would really appreciate some feedback if there is a way to align these two objects centered on the two selected faces.

 

 

Message 13 of 15
Ralf_Krieg
in reply to: ga42bon

Hello

 

Sorry, don't have an idea how to solve this. Don't know if it is possible to calculate the center of a curved surface.

 

Meanwhile I realized in my sample above, if you have a face in a "L" form, the center lies outside the face.


R. Krieg
RKW Solutions GmbH
www.rkw-solutions.com
Message 14 of 15
Michael.Navara
in reply to: ga42bon

May be this can solve your task. It doesn't return exactly center of face, but some point near to them.

This example works in part environment. 

 

Dim oFace As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Select face")
Dim paramRangeRect As Box2d = oFace.Evaluator.ParamRangeRect

Dim x As Double = (paramRangeRect.MaxPoint.X + paramRangeRect.MinPoint.X) / 2
Dim y As Double = (paramRangeRect.MaxPoint.Y + paramRangeRect.MinPoint.Y) / 2

Dim params As Double() = {x, y}
Dim points As Double() = {}
oFace.Evaluator.GetPointAtParam(params, points)

Logger.Debug(String.Join("; ", points))

Dim partDef As PartComponentDefinition = oFace.Parent.Parent
partDef.WorkPoints.AddFixed(ThisApplication.TransientGeometry.CreatePoint(points(0), points(1), points(2)))

 

Message 15 of 15
ga42bon
in reply to: ga42bon

Hello @Ralf_Krieg,

Thanks for taking the time and thinking about my problem. You helped me a lot with the planar faces.

 

@Michael.Navara:

This is a very good solution for slightly curved faces. Thanks a lot!

Now I can align a great amount of different objects. 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report