Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Smart face zoom (LookAt & ZoomToSelected)

Maxim-CADman77
Advisor

Smart face zoom (LookAt & ZoomToSelected)

Maxim-CADman77
Advisor
Advisor

I'm now working on app that is supposed to zoom some face-of-interest (mainly spheric) smartly (rotate and zoom part body so that the face was clearly distinguished).

Initially my intent was to calculate coordinates of two RangeBox Center-Points (Part's and Face Evaluator's) and  use them as Target and Eye for setting Camera also doing FindInWindow and ZoomTo commands.

I did this succsessfully just to find out that this behaviour is faulty for internal faces of shell-like parts - the Face is shown from the wrong (inner) side.

I now understand that what I need is closer to combination of LookAt & ZoomToSelected commands while the Perspective mode is on. Yet, LookAt command can be applied to plain faces only.

I believe that to achieve my goal I need to get just one more stuff - positive direction of the Face at a given point (its Center). I then should somehow be able to transform that Vector to new Eye-Point.

I thought I need to use FaceProxy but I see this object relates to Assemblies.

So I don't know where to look at now.

Could, please somebody hint me a bit?

Thanks in advance.

PS: I've attached a sample IPT with the only spheric Face marked red

My current code (iLogic)

If ThisDoc.Document.DocumentType=DocumentTypeEnum.kPartDocumentObject then
	Dim oTG As TransientGeometry=ThisApplication.TransientGeometry
	Dim oCam As Camera=ThisApplication.ActiveView.Camera
	Dim oIPT As PartDocument=ThisDoc.Document
	Dim oCD As ComponentDefinition=oIPT.ComponentDefinition
	Dim oSB As SurfaceBody=oCD.SurfaceBodies(1) ' usage of a smarter way of choosing "Body-of-Interest" is supposed !!!
	Dim oBMP As Point= oTG.CreatePoint((oSB.RangeBox.MinPoint.X+(oSB.RangeBox.MaxPoint.X-oSB.RangeBox.MinPoint.X)/2),(oSB.RangeBox.MinPoint.Y+(oSB.RangeBox.MaxPoint.Y-oSB.RangeBox.MinPoint.Y)/2),(oSB.RangeBox.MinPoint.Z+(oSB.RangeBox.MaxPoint.Z-oSB.RangeBox.MinPoint.Z)/2)) ' Body Mid-Point
	Dim oFRB as Box ' Face-of-Interest RangeBox
	Dim oFMP As Point ' Face Mid-Point
	oCAM.Target=oBMP
	For Each oFace As Face in oSB.Faces
		If oFace.SurfaceType=SurfaceTypeEnum.kSphereSurface then
			oIPT.SelectSet.Select(oFace)
			oFRB=oFace.Evaluator.RangeBox
			oFMP=oTG.CreatePoint((oFRB.MinPoint.X+(oFRB.MaxPoint.X-oFRB.MinPoint.X)/2),(oFRB.MinPoint.Y+(oFRB.MaxPoint.Y-oFRB.MinPoint.Y)/2),(oFRB.MinPoint.Z+(oFRB.MaxPoint.Z-oFRB.MinPoint.Z)/2))
			oCam.Eye = oFMP
			oCam.Perspective=True
			oCam.ApplyWithoutTransition
			ThisApplication.CommandManager.ControlDefinitions("AppZoomSelectCmd").Execute
			' oIPT.SelectSet.Clear
	Exit For
		End if 
	Next
Else
	MsgBox ("IPT should be active")
End if

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Reply
Accepted solutions (1)
1,131 Views
9 Replies
Replies (9)

JelteDeJong
Mentor
Mentor
Accepted solution

try this:

Dim doc As PartDocument = ThisDoc.Document
Dim face As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "")
Dim camera As Camera = ThisApplication.ActiveView.Camera

'get the midpoint param from selected surface
Dim paramRangeRect As Box2d = face.Evaluator.ParamRangeRect
Dim params(1) As Double
params(0) = (paramRangeRect.MaxPoint.X + paramRangeRect.MinPoint.X) / 2
params(1) = (paramRangeRect.MaxPoint.Y + paramRangeRect.MinPoint.Y) / 2

'get point on surface at param
Dim points(2) As Double
face.Evaluator.GetPointAtParam(params, points)
Dim target As Point = ThisApplication.TransientGeometry.CreatePoint(points(0), points(1), points(2))

' next line is only for debug to show what the camera target is 
doc.ComponentDefinition.WorkPoints.AddFixed(target)
camera.Target = target

'get the normal of the surface at target point
'translate target point with normal-vector to eye point
Dim normals(2) As Double
face.Evaluator.GetNormal(params, normals)
Dim normal As Vector = ThisApplication.TransientGeometry.CreateVector(normals(0), normals(1), normals(2))
Dim eye As Point = target
eye.TranslateBy(normal)

' next line is only for debug to show what the camera eye is 
doc.ComponentDefinition.WorkPoints.AddFixed(eye)
camera.Eye = eye

'you might want to set also the upvector to rotate the view to something more sensible.
'but i dont know how....
'camera.UpVector = ???

camera.ApplyWithoutTransition()

' i tryed to soom to selected surface with the camera but did not manage
' therefor this hack
doc.SelectSet.Clear()
doc.SelectSet.Select(face)
ThisApplication.CommandManager.ControlDefinitions.Item("AppZoomSelectCmd").Execute()

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

0 Likes

Maxim-CADman77
Advisor
Advisor

I wish somebody explain me what is Evaluator.ParamRangeRect for the Face...

Please vote for Inventor-Idea Text Search within Option Names

0 Likes

JelteDeJong
Mentor
Mentor

have a look at this:

https://modthemachine.typepad.com/files/mathgeometry.pdf 

at page 9 you will find more info. (but i needed to read page 1 to 8 to understand it.)

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

0 Likes

Maxim-CADman77
Advisor
Advisor

Oops!

The life occured to be a bit more complicated.

I've just found at least one IPT where the solution doesn't work (tries to show the face from the side of material).

It is one of ContentCenter Files.

It is even more interesting that the very close looking part from another CC family doesn't have this issue.

Please find the two samples attached

Please vote for Inventor-Idea Text Search within Option Names

0 Likes

Maxim-CADman77
Advisor
Advisor

After diging a bit I've found that there is some uncertanty in the part of code responsible for target point coordinates calculation.

It does not take into a count the real geometry of a (?spheric?) face and thus can give a point opposite* to the point-of-interest (not belonging to surface of the solid).

It is declared that "The SurfaceEvaluator object can be obtained either from the Face object or from any of the surface geometry objects. It’s generally better to use the evaluator on the Face object since it takes into account additional information provided by the solid."

The tiny-little-thing remained unclear - how the code should be modified in order Face.Evaluator.GetPointAtParam return only Point belonging to the Face.  

 

* transient geometry surfaces are boundless 

Please vote for Inventor-Idea Text Search within Option Names

0 Likes

Maxim-CADman77
Advisor
Advisor

After adding line

MsgBox ("Real solution found - " & face.Evaluator.IsParamOnFace(params))

before " 'get point on surface at param" I'm getting 

"True" - for "NORMAL" IPT-sample 

and

"False" - for "FAULTY" IPT-sample 

...thus face.Evaluator.ParamRangeRect is for blame?

Please vote for Inventor-Idea Text Search within Option Names

0 Likes

Maxim-CADman77
Advisor
Advisor

After executing API Helps "3D Curve from Parametric Curve API Sample" code on both IPT-samples I beging to doubt that ParamRangeRect is worth to use for solving initial task. Problem It's not just opposit direction of point. In fact zero-parameter curve doesn't fit the edge of real face:

ParamRangeRect_OnSphericFace_Visualisation.png

Please vote for Inventor-Idea Text Search within Option Names

0 Likes

Maxim-CADman77
Advisor
Advisor

As far as I don't understand how to workaround smartly I've added the simple check with camera points inversion if necessary. The updated code is:

Dim doc As PartDocument = ThisDoc.Document
Dim oCD As ComponentDefinition=doc.ComponentDefinition
Dim face As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "")
Dim camera As Camera = ThisApplication.ActiveView.Camera

'get the midpoint param from selected surface
Dim paramRangeRect As Box2d = face.Evaluator.ParamRangeRect
Dim params(1) As Double
params(0) = (paramRangeRect.MaxPoint.X + paramRangeRect.MinPoint.X) / 2
params(1) = (paramRangeRect.MaxPoint.Y + paramRangeRect.MinPoint.Y) / 2

Dim IsSolved As Boolean = True
IsSolved = face.Evaluator.IsParamOnFace(params) 'get point on surface at param Dim points(2) As Double face.Evaluator.GetPointAtParam(params, points) Dim target As Point = ThisApplication.TransientGeometry.CreatePoint(points(0), points(1), points(2)) Dim NewPoints(2) As Double If Not IsSolved And face.SurfaceType=SurfaceTypeEnum.kSphereSurface Then NewPoints(0)=points(0)-2*(points(0)-face.Geometry.CenterPoint.X) NewPoints(1)=points(1)-2*(points(1)-face.Geometry.CenterPoint.Y) NewPoints(2)=points(2)-2*(points(2)-face.Geometry.CenterPoint.Z) target = ThisApplication.TransientGeometry.CreatePoint(NewPoints(0), NewPoints(1), NewPoints(2)) End If ' ' this section is only for debug to show what the camera target is ' Try ' oCD.WorkPoints("Target").Delete ' Catch ' End Try ' oWP=oCD.WorkPoints.AddFixed(target) ' oWP.Name="Target" camera.Target = target 'get the normal of the surface at target point 'translate target point with normal-vector to eye point Dim normals(2) As Double face.Evaluator.GetNormal(params, normals) If Not IsSolved then normals(0)=-normals(0) normals(1)=-normals(1) normals(2)=-normals(2) End If Dim normal As Vector = ThisApplication.TransientGeometry.CreateVector(normals(0), normals(1), normals(2)) Dim eye As Point = target eye.TranslateBy(normal) ' ' this section is only for debug to show what the camera eye is ' Try ' oCD.WorkPoints("Eye").Delete ' Catch ' End Try ' oWP=oCD.WorkPoints.AddFixed(eye) ' oWP.Name="Eye" camera.Eye = eye 'you might want to set also the up-vector to rotate the view to something more sensible. 'but i don't know how.... 'camera.UpVector = ??? camera.ApplyWithoutTransition() ' i tried to zoom to selected surface with the camera but did not manage ' therefor this hack doc.SelectSet.Clear() doc.SelectSet.Select(face) ThisApplication.CommandManager.ControlDefinitions.Item("AppZoomSelectCmd").Execute()

I believe it is far from ideal, yet, It does the trick for the partipular FAULTY sample I've uploaded earlier...

Please vote for Inventor-Idea Text Search within Option Names

0 Likes

llorden4
Collaborator
Collaborator

I too had struggled with changing camera view to a face and searching the web hasn't been very fruitful short of this post.  For myself, I'm looking just to change a camera view while in the model.  Piecing together codes from a couple of posts and examples I've found, sharing below my particular blend of code to accomplish my goal and posting in the event someone else can find it useful.

'find focus face and UP direction
Dim params(1) As Double
Dim normals(2) As Double
Dim oCam As Camera = ThisApplication.ActiveView.Camera
Dim oBox As Box
Dim oNormal As Vector
Dim oUp As UnitVector
Dim Eye As Point
Dim Pnts(1) As Point
Dim oLine(1) As Line
oFace1 = iLogicVb.Automation.GetNamedEntities(ThisDoc.Document).TryGetEntity("Flat " & CStr(fMin))			'find first flat
oFace2 = iLogicVb.Automation.GetNamedEntities(ThisDoc.Document).TryGetEntity("Start Edge")					'find adjacent starting edge
For i = 1 To oFace1.Edges.Count
	For j = 1 To oFace2.Edges.Count
		If oFace1.Edges.Item(i).GeometryType = 5123 And oFace2.Edges.Item(j).GeometryType = 5123 Then		'Find only Line Segment types on outside faces
			Pnts(0) = oFace1.Edges.Item(i).StartVertex.Point
			oLine(0) = oTG.CreateLine(Pnts(0), oFace1.Edges.Item(i).StartVertex.Point.VectorTo(oFace1.Edges.Item(i).StopVertex.Point))
			Pnts(0) = oFace2.Edges.Item(j).StartVertex.Point
			oLine(1) = oTG.CreateLine(Pnts(0), oFace2.Edges.Item(j).StartVertex.Point.VectorTo(oFace2.Edges.Item(j).StopVertex.Point))
			If oLine(0).IsColinearTo(oLine(1)) Then
				If oFace1.Edges.Item(i).StartVertex.Point.Y < oFace1.Edges.Item(i).StopVertex.Point.Y Then
					oUp = oTG.CreateLineSegment(oFace1.Edges.Item(i).StartVertex.Point, oFace1.Edges.Item(i).StopVertex.Point).Direction
				Else
					oUp = oTG.CreateLineSegment(oFace1.Edges.Item(i).StopVertex.Point, oFace1.Edges.Item(i).StartVertex.Point).Direction
				End If
			End If
		End If
	Next
Next

oFace = iLogicVb.Automation.GetNamedEntities(ThisDoc.Document).TryGetEntity("Flat " & CStr(fMin))
oBox = oFace.Evaluator.RangeBox
oCam.Target = oTG.CreateLineSegment(oBox.MinPoint, oBox.MaxPoint).MidPoint
oFace.Evaluator.GetNormal(params, normals)
oNormal = ThisApplication.TransientGeometry.CreateVector(normals(0), normals(1), normals(2))
Eye = oCam.Target
Eye.TranslateBy(oNormal)
oCam.Eye = Eye
oCam.UpVector = oUp
oCam.Apply
ThisApplication.ActiveView.Fit
InventorVb.DocumentUpdate(True)
oUnFold = oCompDef.Features.UnfoldFeatures.Add(oFace)
oUnFold.Name = "CNC Flat Layout"

 

Autodesk Inventor Certified Professional
0 Likes