Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Sketch.offset doesn't handle negative offsets

11 REPLIES 11
SOLVED
Reply
Message 1 of 12
ross.korsky
1240 Views, 11 Replies

Sketch.offset doesn't handle negative offsets

It appears that Sketch.offset does not handle negative offsets - the behavior I observe is the same if i provide no offset, zero offset, or a negative offset...

 

So, my question is this. Given a closed shape how can I reliable "grow" or "shrink" it? I need a way to find a point that is either "outside" or "inside" the shape respectively.

 

I can code up my own solution using ray crossing (draw an infinite, or sufficiently large, line from some point in any direction and count how many times it crosses the shape - odd: the point is inside the shape; even: the point is outside). But, in my case, it'd be so much easier if offset just allowed me to use a negative value; then i could simply use sketch.modelToSketchSpace(face.pointOnFace) as a point known to be "inside" the outer loop and "outside" any inner loops.

11 REPLIES 11
Message 2 of 12
ross.korsky
in reply to: ross.korsky

As I'm working with a solid body as a base for my current efforts I can try to take advantage of adjacent faces to determine which way is out. However, the "Fusion Solids and Surfaces" help page states

 

"

In general, it is best to use the evaluators on the B-Rep objects, rather than the geometry objects because the BRep object evaluators take into account the rest of the body. For example, getting a normal using the evaluator from a geometry object cannot guarantee that the normal direction will point out of the solid. This is because the geometry evaluator knows nothing about the structure of the solid.

"

But fails to state how to get an evaluator for a BRepBody. Indeed I'm observing that the normals I get from the adjacent faces sometimes point into the body.

 

 

Something else that i've encountered is that BRepEdge.pointOnEdge doesn't always give me a point that is actually on the edge - which is in contrast to what the help page states. In this case the selected face was the product of a chamfer.

PrQBxkf

 

Message 3 of 12
ekinsb
in reply to: ross.korsky

There's no argument that this couldn't be simpler.  The problem is that the API needs to handle all cases, which means open and closed shapes.  For closes shapes it's simple but specifying a positive or negative value for an open shape doesn't help define which direction the offset will be.  A point is unambiguous but unfortunately is sometimes difficult to determine.  And the ray crossing code has already been written if you want to take advantage of that. 


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 4 of 12
ross.korsky
in reply to: ekinsb

Where can I find the existing ray crossing code? I mean I know the internet is full of it - I'm hoping for an existing fusion sketch specific solution here 😉

 

I'm about to try something with coEdges, but honestly I think i'd have more confidence in the ray-crossing solution at this point.

Message 5 of 12
ross.korsky
in reply to: ross.korsky

... Also I fail to see how offset could not support negative offsets. Open or closed + means offset in the direction of the given point and - means offset the other way. Heck the Fusion UI already does this which is why i was surprised that the API did not behave similarly.

Message 6 of 12
ekinsb
in reply to: ross.korsky

Sorry about that.  Had the link in my copy buffer and forgot to paste it.  Here it is:

 

http://forums.autodesk.com/t5/api-and-scripts/how-to-determine-a-directionpoint-to-offset-an-arbitra...

 

Regarding your other questions about getting the normal from B-Rep objects instead of the geometry, that means that you can get different directions for a normal if you get the SurfaceEvaluator directly from a BRepFace or if you first get the geometry (Cylinder, Plane, NurbsSurface, etc.) from the face and then get the SurfaceEvaluator from it.  Because the face has access to the Solid topology the normal will always point "out" of the solid, whereas for surface geometry it doesn't have that intelligence and the normal can go in either direction.

 

Also, regarding that you're getting points on the edge with the pointOnEdge method.  I am able to reproduce that this is a problem and will file a bug.  The good news is that is fairly easy using the CurveEvaluator3D that you get from the edge to calculate your own point along the edge.  But we'll still get this fixed.


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 7 of 12
ekinsb
in reply to: ross.korsky

Regarding about the API taking a positive or negative value.  Sure we could do that but it doesn't really help if you also have to supply a point to indicate a direction.  But maybe I'm missing something because I think it would be easy to support if it provides a benefit. 


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 8 of 12
ross.korsky
in reply to: ekinsb


@ekinsb wrote:

Regarding about the API taking a positive or negative value.  Sure we could do that but it doesn't really help if you also have to supply a point to indicate a direction.  But maybe I'm missing something because I think it would be easy to support if it provides a benefit. 


Well, in my use case it's trivial to get a "point on face". Then as I traverse the edges I know if a loop isOuter or not and given that I have a point "on the face" I could trivially offset the outer loop in the positive direction and the inner loops in the negative direction and be assured that all edges moved in such a way to "grow" the shape (for subtractive manufacturing cases e.g. laser cutting) or reverse to "shrink" the shape (for additive manufacturing cases, e.g. 3D printing). 

 

Another simple usecase would be: I have a circle and i want to grow or shrink it - using the center point as the offset "side" indication would make enlarging or shrinking it trivial. Without negative offsets i would actually need to compute a point which lies outside the circle - granted in this case it's not too hard to do as a circle is very regular - so how about an ellipse at an angle... again I suppose i could take the major axis and compute a point known to be outside of the ellipse... 

 

but really, and more to the point - why doesn't offset support Negative numbers? what possible reason would there be to add such an arbitrary restriction? 

 

P.S. I've commented on the help page about the negative offset behavior NOT being mentioned there.

Message 9 of 12
ekinsb
in reply to: ross.korsky

I agree that it could be useful and have added an item to our backlog that we'll prioritize with the rest of the work.


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 10 of 12
ross.korsky
in reply to: ekinsb


@ekinsb wrote:

 

Regarding your other questions about getting the normal from B-Rep objects instead of the geometry, that means that you can get different directions for a normal if you get the SurfaceEvaluator directly from a BRepFace or if you first get the geometry (Cylinder, Plane, NurbsSurface, etc.) from the face and then get the SurfaceEvaluator from it.  Because the face has access to the Solid topology the normal will always point "out" of the solid, whereas for surface geometry it doesn't have that intelligence and the normal can go in either direction.

 

Here's the action i'm taking in my (python) code:

 

 

 

face = adsk.fusion.BRepFace.cast(selection.entity)
....
    for loop in face.loops:
      if loop.isOuter:
        for edge in loop.edges:
          sample_point = edge.pointOnEdge
          faces = edge.faces
          assert faces.count == 2
          faces = [f for f in faces if f.tempId != face.tempId]
          assert len(faces) == 1, 'Expected 1 face but found {}.'.format(len(faces))
          (r, norm) = faces[0].geometry.evaluator.getNormalAtPoint(sample_point)
          assert r, 'Failed to get normal'

 

 

and, as you can see in my previous image, I get normals that point INTO my body - granted in this case the normal in question is based on a line well off the body geometry but the same artifact happens on any edge adjacent to the "bottom" of the body - those normals always point "up" not "out".

 

Is this the wrong way to get the evaluator?

 


@ekinsb wrote:

 

Also, regarding that you're getting points on the edge with the pointOnEdge method.  I am able to reproduce that this is a problem and will file a bug.  The good news is that is fairly easy using the CurveEvaluator3D that you get from the edge to calculate your own point along the edge.  But we'll still get this fixed.


Thanks!

Message 11 of 12
ekinsb
in reply to: ross.korsky

You're getting the evaluator from the geometry associated with the face and that's the case where the normal is arbitrary.  Instead of:

 

(r, norm) = faces[0].geometry.evaluator.getNormalAtPoint(sample_point)

 

You should be doing:

 

(r, norm) = faces[0].evaluator.getNormalAtPoint(sample_point)

 


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 12 of 12
ross.korsky
in reply to: ekinsb

Thanks!

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report