BUG in Draft.makeCircle()
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
BUG in Draft.makeCircle()
Hi,
I think there is a BUG in Draft.makeCircle() from Part.ArcOfCircle()
The arc created by Draft.makeCircle() NOT coincide with the arc created by Part.ArcOfCircle() (the arc created by Part.ArcOfCircle() it is right, it touch the points, the other by Draft.makeCircle() do not touch!)
Need open a BUG report?
Thanks
Dino
OS: Devuan GNU/Linux beowulf/ceres
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.18.
Build type: Release
Python version: 2.7.16rc1
Qt version: 5.11.3
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: Italian/Italy (it_IT)
I think there is a BUG in Draft.makeCircle() from Part.ArcOfCircle()
The arc created by Draft.makeCircle() NOT coincide with the arc created by Part.ArcOfCircle() (the arc created by Part.ArcOfCircle() it is right, it touch the points, the other by Draft.makeCircle() do not touch!)
Need open a BUG report?
Thanks
Dino
OS: Devuan GNU/Linux beowulf/ceres
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.18.
Build type: Release
Python version: 2.7.16rc1
Qt version: 5.11.3
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: Italian/Italy (it_IT)
- Attachments
-
- ArcFromArc.png (42.23 KiB) Viewed 1265 times
- Joel_graff
- Veteran
- Posts: 1949
- Joined: Fri Apr 28, 2017 4:23 pm
- Contact:
Re: BUG in Draft.makeCircle()
This is not a bug. It's simply curve tessellation. The tessellations don't align because the beginning and ending points of your arcs are not aligned.
The arcs are mathematically precise and if you discretize them (using Shape.discretize()), they will provide coordinates along the perimeter of the arc without error. The visual representation is, of course, less accurate because it is subdivided into straight-line segments (or tessellated).
You can control the visual accuracy by editing the Part Design Preferences as follows:
- Open Edit->Preferences
- Click on the 'Part Design' icon on the left.
- Select the 'Shape View' tab at the top on the right.
You can reduce that percentage to as low as 0.01%. If you rebuild your objects, you'll very likely find they look much smoother. Of course, if you zoom in far enough, you'll see the tessellation clearly.
Note that the percentage is based on the size of the model bounding box - it's not a fixed length. So a much larger object will have much larger tessellations at the same percentage. In order to avoid that, you need to plot the arc manually as a wire, calculating the points using the equation of a circle. Or you can discretize the existing arc to get a list of closely-spaced points and build a Wire from those.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails
pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
Re: BUG in Draft.makeCircle()
No, this not is a curve tessellation, if you run the script will see that the error is real, measure distance from the end of the Shape and Circle and see that it is a BIG error (4.81434mm)
Re: BUG in Draft.makeCircle()
Dear,
the error is in Mod/Draft/Draft.py at line 709, the reference vector is horizontal East direction not "placement.multVec(FreeCAD.Vector(1,0,0))".
Need to correct it!
To whom should the reported the BUG?
Have a nice day
Dino
the error is in Mod/Draft/Draft.py at line 709, the reference vector is horizontal East direction not "placement.multVec(FreeCAD.Vector(1,0,0))".
Need to correct it!
To whom should the reported the BUG?
Have a nice day
Dino
- Joel_graff
- Veteran
- Posts: 1949
- Joined: Fri Apr 28, 2017 4:23 pm
- Contact:
Re: BUG in Draft.makeCircle()
My mistake - I see what you're referring to, now.
Obviously, Part.ArcOfCircle builds the arc from pre-defined vertices, whereas Draft.makeCircle essentially needs a start angle, end angle, and radius to create the arc. In FreeCAD, arc angles are measured from the positive x-axis (east - Vector(1,0,0)) not the positive y-axis (north - Vector(0,1,0)).
While it's certainly inconvenient for those of us who prefer angles measured from true north (myself included), this is not a bug. You'll simply need to account for this difference in convention in the calculation of your Part.ArcOfCircle vertices.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails
pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
Re: BUG in Draft.makeCircle()
The method to convert an arc from the form of Part.ArcOfCircle to the Draft form was not implemented by me, I simply used Draft.makeCircle(edge) which contains a BUG, an incorrect vector is taken as a reference to calculate the start and end angles of the arc.
the correct ref vector is
Code: Select all
def makeCircle(radius, placement=None, face=None, startangle=None, endangle=None, support=None):
... cut ...
if isinstance(radius,Part.Edge):
edge = radius
if DraftGeomUtils.geomType(edge) == "Circle":
obj.Radius = edge.Curve.Radius
placement = FreeCAD.Placement(edge.Placement)
delta = edge.Curve.Center.sub(placement.Base)
placement.move(delta)
if len(edge.Vertexes) > 1:
ref = placement.multVec(FreeCAD.Vector(1,0,0))
v1 = (edge.Vertexes[0].Point).sub(edge.Curve.Center)
v2 = (edge.Vertexes[-1].Point).sub(edge.Curve.Center)
a1 = -math.degrees(DraftVecUtils.angle(v1,ref))
a2 = -math.degrees(DraftVecUtils.angle(v2,ref))
obj.FirstAngle = a1
obj.LastAngle = a2
else:
... cut ...
Code: Select all
ref = FreeCAD.Vector(1,0,0)
- Joel_graff
- Veteran
- Posts: 1949
- Joined: Fri Apr 28, 2017 4:23 pm
- Contact:
Re: BUG in Draft.makeCircle()
I think I finally see your point. It dawned on me that you're defining the arc using an existing shape (instead of points - which works perfectly). I agree, it does look wrong.
Pinging Yorik on this.
yorik wrote: ping
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails
pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
Re: BUG in Draft.makeCircle()
I have checked my solution proposed here and works correctly only if the arc is on XY plane, if rot the arc in the space before converting it fail again, because need to check the plane on the arc is rapresented. In next days I try to correct it.
- Joel_graff
- Veteran
- Posts: 1949
- Joined: Fri Apr 28, 2017 4:23 pm
- Contact:
Re: BUG in Draft.makeCircle()
You can submit a pull request for the fix if you like, if you know your way around git... Otherwise, give @yorik (or @wmayer) time to look at it and address it. We're in the middle of a release, so they may not get to it right away.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails
pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
Re: BUG in Draft.makeCircle()
Ok,
I have corrected the BUG (I think )
The correct code is:
Please can check it?
D
I have corrected the BUG (I think )
The correct code is:
Code: Select all
cut...
if isinstance(radius,Part.Edge):
edge = radius
if DraftGeomUtils.geomType(edge) == "Circle":
obj.Radius = edge.Curve.Radius
placement = FreeCAD.Placement(edge.Placement)
delta = edge.Curve.Center.sub(placement.Base)
placement.move(delta)
# Rotation of the edge
rotOk = FreeCAD.Rotation(edge.Curve.XAxis, edge.Curve.YAxis, edge.Curve.Axis, "ZXY")
placement.Rotation = rotOk
if len(edge.Vertexes) > 1:
#ref = placement.multVec(FreeCAD.Vector(1,0,0))
#ref = ref.sub(edge.Curve.Center)
v1 = (edge.Vertexes[0].Point).sub(edge.Curve.Center)
v2 = (edge.Vertexes[-1].Point).sub(edge.Curve.Center)
#a1 = -math.degrees(DraftVecUtils.angle(v1,ref))
#a2 = -math.degrees(DraftVecUtils.angle(v2,ref))
v0 = (edge.Curve.XAxis).normalize()
v1.normalize()
v2.normalize()
# Angle between edge.Curve.XAxis and the vector from center to start of arc
obj.FirstAngle = math.degrees(math.acos((v0.x*v1.x)+(v0.y*v1.y)+(v0.z*v1.z)))
# Angle between edge.Curve.XAxis and the vector from center to end of arc
obj.LastAngle = math.degrees(math.acos((v0.x*v2.x)+(v0.y*v2.y)+(v0.z*v2.z)))
cut...
D