-
Notifications
You must be signed in to change notification settings - Fork 8
Added Cubic and PolyBezier Curves #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Added Cubic and Quadratic Bezier curves for smoother outskin edge calculations leading to a smoother surface finish
Fixed Spacing
|
Hello Mr. Tanner, thank you for your Pull Request. In general, we endorse the integration of additional geometric spline types, especially if there is industry need. Because OVF is based on Protocol Buffers (protobuf) and code generators, we can roll out format additions quickly. The rules for protobuf forwards-/ backwards compatibility
Because we cannot remove or rename a field after adding, I would like to discuss a few points before merging. Observations
Discussion Points Summary
|
|
Hello Mr Dirks, Thank you for getting back with me so quickly. Our specific use case Includes a jump to a specific start point followed by a sequence of curves following the format control point, target point. [Cx0,Cy0,Tx0,Tx0,Cx1,Cy1,Tx1…]. For Quadratic Bezier this involves two control points. In the future we may also utilize the hatching feature for infill on our parts. I agree that compressing identical points is a good idea, however dropping the control points at the nth tail segment causes issues for our use case. We are drawing a curve relative to our current position and those control points define the curve to our target. I think one solution that works well with our use case would be ` //Quadratic Bézier segments. //Cubic Bézier segments. //Linked Quadratic Bézier segments. //Linked Cubic Bézier segments. As for NURBS and other curve types I do not see an urgent need at them moment. With the flexibility provided by the protobuf format OVF can adapt with the industry. Thank you so much and I look forward to your feedback. |
Updates to compress data and differentiate between hatches and splines
|
Hello Mr. Tanner, thank you for the update. We have requested a review from Dyndrite as well for this PR. This should be done in the next few days, afterwards I will merge. I have other additions for lookahead based scanners on a branch that I will also merge. Then I will put together a new release version of OVF. Best |
|
Hello Mr. Dirks, Thank you. I look forward to their feedback and to the next release version. Thank you for your help. Respectfully, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a reason why we couldn't proceed on our end with these changes. That said, I did have some observations and comments to share.
- Several of these messages put special meaning on values in a sequence, such as the various "Initial segment" values. Does it make sense to pull these out into explicit fields so that the repeated field is homogenous in intent? Other messages within the spec seem to do similar (Eg. the
Arcmessage) - I have concerns regarding the unstructured nature of using
repeated floatinstead of composing and repeating more meaningful messages. There could be too many / too few values, or value-misalignment, within the message. Seeing as extant parts of the OVF protobuf specification already leveragerepeated float, I don't see a compelling reason to depart from convention. That said, I do think it is worthwhile to document expected behavior when such fields are malformed. (Or otherwise specifically citing that handling of such malformed entities is undefined by the specification). - I'm curious about constraining the order of the curve to N ∈ {2, 3} rather than leveraging the general Bézier curve definition? Is there a computational constraint or scalability concern that I'm not accounting for?
-
A rough draft of using general curve definitions:
// NOTE: 2d definitions for all here, 3d left as an exercise to the reader. message GeneralBezierCurve { float x_0 = 1; float y_0 = 2; float x_n = 3; float y_n = 4; repeated float control_point_data = 5; } message BezierHatches { repeated GeneralBezierCurve segments = 1; } // A component within a spline composed by individual bezier curves. // Each starts from the previous components target, is interpolated through its // control poitns to its own target x/y values. message GeneralBezierCurveSplineComponent { // the target point. float x = 1; float y = 2; // The control points to use leading into `{x, y}` repeated float control_point_data = 3; } message BezierSpline { float ix = 1; float iy = 2; repeated GeneralBezierCurveSplineComponent = 3; }
-
|
Thank you so much for your timely response, I understand what you are attempting to accomplish, but I am unsure of the practicality and usefulness of such a change. Supporting arbitrary-degree Béziers forces variable-degree evaluation leading to an exponential compute time (de Casteljau ~O(dn²) per sample). In practice our controllers accelerate quad/cubic only and higher degrees will get flattened anyway, adding cost without quality gain. Fixed length bezier curves keeps streaming lightweight and predictable in my opinion. Switching to general, nested messages increases payload size and decoder complexity, and would require all readers to implement flattening. I think keep quad/cubic as the primary wire format. I agree, documenting expected behavior from a misaligned float does pose a risk, however I hesitate to depart from convention without a compelling reason. For our current use case repeated float segments keep it as lightweight and predictable as possible, however I might be blind to the needs of the industry outside of our own implementation. I appreciate any feedback you may have for me. Thank you. Respectfully, |
|
Thank you both for your detailed feedback. I want to add details on the previous design choices for OVF that lead to the repeated float design for Polyline types, and add my toughts on the different proposals. OVF perf: why unstructured repeated float?@dyn-sdunn The choice of using unstructured repeated float in OVF is very deliberate and the reasoning is performance. Approx. 99% of the data volume in OVF is the coordinate data. Let me use the example of Polyline2d. wire format consequencesEncoding the Point structured in protobuf would lead to a different encoding "on the wire". Each message of a repeated embedded message field needs its own tag for the message (min 1 byte), length of the message (min 1 byte) and a tag for each field (1 byte for x, 1 byte for y). What we have now is a single tag and length for ALL floats, which is neglectable serialization overhead for typical block sizes. The repeated float field is "parsed" with a memcopy based on the length from the network buffer/file stream buffer to the proto object float array. The structured embedded message adds 4 bytes of overhead per 2 floats. This would increase file size by at least 50%. Even worse, each length and tag is a varint and has to be parsed with branch heavy code on a single byte level with bit masks instead of a bulk memcopy. vector blocks and machine controller capabilitiesThe Vector Block types serve as an extension point in OVF that represent controller capabilities. The intended design for OVF machine controllers is basically a switch statement on the vector block type to execute the desired exposure. It is not necessarily desirable to make the Vector Block design the most general possible, because as Mr. Tanner noted that also requires the machine controller to implement the most general form although it might never be used. the pros and cons of generalityI would also prefer a more straightforward definition that can be memcast to common structs used in the geometry libraries. If the need for higher degree Bezier (or other Spline types) arises, this can simply be implemented with another vector block type, which is an optional capability. Converting complex and general definitions to primitive forms on the machine controller can be efficient if it reduces data volume and reduces discretization errors, but I think for Bezier it would just add a nested swich statement in the handling of the vector block type. representation of initial segments and strided memory accessI also want to elaborate on the initial segments comment by Samuel. useful feedback to move forward@Samtanner12 as far as I understood your software uses the full struct (with start and end point) for splines. The "array of structs with stride" pattern can also be used with the definition proposed by Samuel, if the 2 floats from the extra fields are appended to the Vector after protobuf has parsed the Vector Block Message. I would then propose to define the last point (end point) instead of the start point in extra fields. This avoids a memmove of the whole backing array of the Vector because we have to insert at the front. This would give e.g. layout (x0, y0, cx0, cy0) for quadratic Bezier struct. Would that work for you, or would you prefer the current proposal with more comprehensive documentation? @dyn-sdunn @dyndrite-gabriel is Dyndrite currently already internally using any fixed size structs for quadratic or cubic Bezier spline segments, or uses libraries that define such structs? If yes, what is their memory layout? Is it directly compatible with one of the proposed definitions or would require transformations? |
|
@SebastianDirks I appreciate your comprehensive breakdown of the various proposals. My current implementation and firmware limitations does require me to use a full struct format. I had not considered the cost of the front insert, and I understand the value of your proposed change to an endpoint definition. I see no reason to not move forward with the proposed definition as far as I am concerned. I look forward to answering any other questions that might be relevant. Thank you. |
Implemented proposed behavior
|
Hi @SebastianDirks @dyndrite-gabriel @dyndrite-gabriel I’ve pushed the proposed updates: Hatches: Quadratic/Cubic (stride 6/8); 3D variants (9/12). Splines: start+control(s) with tail end point; 3D variants included. Kept packed repeated float convention; Let me know if you have any questions or concerns. thank you. |
Added Cubic and PolyBezier Curves to the proto definition. Polybezier curves allow for a quicker curve calculation and more accurate position on the curve facilitating a smoother surface finish. This change will allow us to use OVF with Dyndrite for our additive solution.