Showing results for 
Search instead for 
Do you mean 
Reply
Solved! Go to solution

API - Get surface/curve at coordinate

I am trying to programmatically return the surface/curve that contains a point a given X,Y,Z coordinate. The only options I have found are the collection of feSelectOutput functions, but these all use a dialog box. What I am looking for is a way to get the surface/curve that contains the specified coordinate without any user interaction. The same process is achieved through the GUI when a surface/curve is selected so I know it is possible, but I do not see it in the API.

 

If anyone has details on how to achieve this it would be greatly appreciated.

11 REPLIES

Re: API - Get surface/curve at coordinate

Hi Meta,

 

you can check all Points in your model, which Points have the required coordinates (with a tolerance). When you found these points, you can use the "Curves" point object method on they (see 5.47.2.3 in Help in API section), or CurvesAsSet (5.47.2.4), SurfacesAsSet (5.47.2.5), Solid (5.47.2.6) methods.

 

Best regards,

 

Peter Kaderasz

Re: API - Get surface/curve at coordinate

Hi,

 

You can avoid checking all points in your model using the set object and the "AddCoordinate2" method: it can find points located near a location, all you need to do is pilot the tolerance.

 

For the rest follow what Peter wrote.

 

AP

Re: API - Get surface/curve at coordinate

Woudl you by chance be able to provide a code block of how to go about this? I am having issues accomplishing it.

 

My example is a 1x1x1 box. My coordinate is at <0, 0.5, 0.5>, so right in the middle. For the tolerance I apply <0, 0.25, 0.25>, so it should be able to pick up some point on that surface. However, after calling set.AddCoordinate2(Femap.zDataType.FT_SURFACE, 0, true, coord, tol), set.Count() still returns 0. Event if I create a Point object at <0, 0.5, 0>, which is along one of the edges, and call point.curves(0, out numCurves, out curveIds), the function returns 0 and null.

 

I'm also curious about the surfacesAsSet. It seems Curves() returns an array, but surfacesAsSet adds the matching surfaces to a set and returns nothing. Does this mean I need to create a temporary set, populate it, query it, and then delete the set each time I want to find a surface?

 

 

Re: API - Get surface/curve at coordinate

Something like this:

 

Sub Main
    Dim App As femap.model
    Set App = feFemap()

    'user specified location and tolerance
    Dim coord(2) As Double, tol(2) As Double
    coord(0) = 0 : coord(1) = 0.5 : coord(2) = 0.5
    tol(0) = 0 : tol(1) = 0.25 : tol(2) = 0.25

    'parameters for AddCoordinate2 method
    Dim flags(2) As Boolean, mode(2) As Long
    For i = 0 To 2
        flags(i) = True  'use x y and z
        mode(i) = 4  'use "at location + tolerance" mode
    Next

    Dim p As femap.Point
    Set p = App.fePoint

    Dim set1 As femap.Set, set2 As femap.Set
    Set set1 = App.feSet
    Set set2 = App.feSet

    'find all points at specified location, within specified tolerance
    set1.AddCoordinate2(FT_POINT,0,flags,mode,coord,tol)

    'for each of these points, find all attached surfaces
    'inject them into set2
    While p.NextInSet(set1.ID)
        p.SurfacesAsSet(FCC_BOTH,set2.ID,False)
    Wend

    'point(s) is (are) connected to these surfaces:
    set2.Debug
End Sub

Re: API - Get surface/curve at coordinate

'find all points at specified location, within specified tolerance

 

When I use your code, it works, but both sets have zero entries. I'm wondering if when you state the above, are these points that are internal to femap? Or do these have to be actual points that the user has created in the model?

 

I increased the tolerance all the way to <0, 0.5, 0.5>, so this encompasses the entire face of the box since the coordinate is in the middle, and AddCoordinate2 still does not place any points in the set.

Re: API - Get surface/curve at coordinate

Hi Meta,

 

the API work, but not with your coordinates. There are any points of solid about coordinate <0, 0.5, 0.5>. See in this picture (inner circle is the tolerance <0, 0,25, 0,25> and the outer circle is the tolerance <0, 0.5, 0,5>:

 

 

When you use coordinate <0, 0.1, 1>, you get in set2 the surfaces IDs 7, 8 and 9 with tolerance <0, 0.25, 0.25>, because the API find here the point ID10 in solid:

 

 

Best regards,

 

Peter Kaderasz

Re: API - Get surface/curve at coordinate

Ah right sorry, I didn't take the time to fully understand what you are asking.

 

If I understand correctly you want to find which surface "passes by" a given point, eventhough it's not a point belonging to the surface (in the FEMAP sense). That is much MUCH harder. But of course not impossible, this is FEMAP we're talking about Smiley Happy

 

The hard part is to find a concept which will be both quick on execution and robust in all cases. I have an idea for the later, but it will be slow:

 

loop on surfaces/curves

      for each surface/curve, project your location onto it

          if the distance between location and projection is smaller than tolerance => bingo!

 

The obvious problem is that you go through all curves/surfaces...

 

So something like:

 

Sub Main
    Dim App As femap.model
    Set App = feFemap()

    'tolerance
    Const tol = 1e-4

    Dim coord(2) As Double, proj As Variant
    Dim d As Double

    Dim surfSet As femap.Set
    Set surfSet = App.feSet
    surfSet.AddAll(FT_SURFACE)

    coord(0) = 0 : coord(1) = 0.5 : coord(2) = 0.5

    While surfSet.Next
        App.feCoordOntoSurface(surfSet.CurrentID,coord,proj)
        App.feMeasureDistance(coord,proj,d)

        If d <= tol Then
            App.feAppMessage(FCM_NORMAL,"Point is on surface #" & CStr(surfSet.CurrentID))
            Exit While  'if you suppose point is only on ONE surface then you might as well exit
        End If
    Wend
End Sub

 

 

 

But again, if you have many surfaces/curves, this is tedious!

 

Unfortunately finding a fast concept is hard (or at least seems hard to me). First off I think you are mistaken when you say "The same process is achieved through the GUI when a surface/curve is selected so I know it is possible": graphical selection is probably very different programmatically than geometrical selection, I have doubts regarding whether one can do what the other does.

 

I think the "true" solution would go through surface facets, perhaps building a clever tree from them (centroid and vertexes) and finding the "close" ones, and only then looking for plausible answers. So not an easy code...

 

 

Oh and one last thing: surfaces have a "InsideXYZ" method, but this will check whether the projection of the location is inside the surface (or at least this is true for planar surfaces), so it will not work for what you are trying to do.

 

AP

Solution
Solution
Accepted by topic author meta
‎10-06-2015 10:41 AM

Re: API - Get surface/curve at coordinate

As long as you are using v11.1 or later there is another alternative. You can use the application method feMeasureDistanceBetweenGeometry( ). This does require you to create a point instead of just using coordinates, but that isn't hard... simply create a Point object, specify the coordinates you want and Put( ) the object. You can then create a Set object of all of your surfaces.. or at least all that you are interested in testing.. and use feMeasureDistanceBetweenGeometry() to find the minimum distance between the point and the surfaces. FEMAP will test all of the surfaces and return the one that is the closest, along with the location of the closest approach and the distance between the two.  To cleanup, you can also simply delete the point.. assuming you don't want it to persist in your model.

Re: API - Get surface/curve at coordinate

Yes, essentially I will have a datum in a CAD model whose <X,Y,Z> coordinate will be directly on a surface, curve, etc. So ideally I would have a coordinate in the center of the surface, and from the coordinate be able to figure out the corresponding femap surface/curve ID. So yes, the point is not a Point construct in the femap model.

 

My thought behind the GUI accomplishing this is that when you move the mouse and hover over surfaces, the corresponding surface is highlighted. However, the more I try it I do realize it is only an estimate because of the 2D screen coordinates (hovering over one surface can highlight another -- not what you want for a programmatic solution!).

 

It seems as if the temporary solution is to do as you say and loop through the points. I will know whether it is a surface or curve, so that will help some.

 

Thanks