CadQuery / cadquery

A python parametric CAD scripting framework based on OCCT
https://cadquery.readthedocs.io
Other
3.06k stars 285 forks source link

2D Drawings with Dimensions #122

Open shrekuntu opened 5 years ago

shrekuntu commented 5 years ago

This is an awesome project and huge improvement over FreeCAD python API. Chainable methods makes it so compact. Excellent work.

However, for me 2D drawings with dimensions are more important then 3D models. I my organization we have lots of relatively simple configurable products and sales cycle is very short, sales guys don't have time to ask Engineering for every customization which are mostly dimensional changes. I understand CQ can be used as a library and possibly from the web app like flask, Web app would interact with user via form data input and return 2D SVG as a result. This can be converted to pdf. STEP model would be offered if needed. But, what is missing are DIMENSIONS. Without dimensions, two similar shape models would look the same, and this is a communication between non-engineers

I read comments in your source code about FreeCAD's SVG Export and wondering if that could be improved with dimensions added and if you have any ideas in that direction.

Thanks

jmwright commented 5 years ago

@shrekuntu I think the work to do autogenerated dimensions would be fairly involved. I don't think there's any plan to add that feature at this time to CadQuery, but we're always willing to accept PRs.

There was also some work done on importing 2D geometry from DXF. Not sure if that helps.

dcowden commented 5 years ago

@shrekuntu

From the very early days, I've hoped we could add 2d parametric behavior into cq.

As Jeremy mentioned there has been a lot of talk about importing dxf and svg. But as you know, these would not produce a parametric design. Retrofitting dimensionality onto a static sketch will not work well.

The best solution is to have a true 2d constraint solver for 2d. This allows building variables in that are automatically computed to suit the others, which may be what you are after.

If you are the simpler ability to allow a user to give values for variables that have designed into a model, so that it can be easily modified, you might have a look at cq parts, which does a much better job than stock cq in this regard.

adam-urbanczyk commented 5 years ago

@shrekuntu good to hear that you like CadQuery! Indeed our SVG export is rather rudimentary. There are no specific plans to include dimensions, although that would certainly be very useful. I agree with @jmwright that adding full-blown dimension generation would be a project in itself and would probably require adding some kind of optimization solver for laying out everything.

Could you share more about your use case? Do you need dimensions for everything or would a simple scale bar suffice?

shrekuntu commented 5 years ago

Here is an example. We are making shafts for power transmission equipment. Shaft has a main diameter, turn down diameter, length, length of turndown, keyways and distance from end to keyway. Only predetermined dimensions would be shown on 2D. User would only fill out an html form with D = 2.4375" (shaft diameter) d = 1.9375" (turn down diameter) L = 44" (shaft length) TD = 9" (turndown length) K = 11" (keyway dist. from end)

User submits this form to a flask app, which in turn sends this to a shaft method with CQ instructions. Once model is done, exports it to svg, add these predetermined dimensions to it and flask app returns svg with dimensions to user. User wouldn't be adding any dimensions on their own, all dims would be predetermined for a type of part

Thanks

dcowden commented 5 years ago

Hah! yes, what you're looking for here was previously implemented on a site I had running for a while called 'parametricparts.com'

The flow was what you want:

(1) user 1 uploads a CQ script, and identifies the metadata for variables that should be exposed to the user. a url is created for that object. The author can change anything. Other users see the view were inputs can be changed (1a) user 1 optionally provides validation logic for the inputs. (2) user #2 visits, and updates the variables. the model is re-created in real time based on the new values, and sees the new model in a window. the result can be downloaded.

The existing CQGI interfaces came from the use case above-- the need to separate the parameters and the metadata associated with it ( friendly names, bounaries, validation logic) from the model was pretty key.

There wasnt a lot of interest, but i thought it worked well. The main reason for lack of interest is that there were very few people who are good at both CAD and programing, so very few people on the planet can make models with CQ. When I shutdown the platform, I think there were about 1000 users, but only about 200 had created models.

On Fri, Apr 26, 2019 at 8:37 AM Shreko notifications@github.com wrote:

Here is an example. We are making shafts for power transmission equipment. Shaft has a main diameter, turn down diameter, length, length of turndown, keyways and distance from end to keyway. Only predetermined dimensions would be shown on 2D. User would only fill out an html form with D = 2.4375" (shaft diameter) d = 1.9375" (turn down diameter) L = 44" (shaft length) TD = 9" (turndown length) K = 11" (keyway dist. from end)

User submits this form to a flask app, which in turn sends this to a shaft method with CQ instructions. Once model is done, exports it to svg, add these predetermined dimensions to it and flask app returns svg with dimensions to user. User wouldn't be adding any dimensions on their own, all dims would be predetermined for a type of part

Thanks

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/CadQuery/cadquery/issues/122#issuecomment-487041618, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJ44A5ABBXHRCTJUWWO6SLPSLZPLANCNFSM4HINAE7Q .

shrekuntu commented 5 years ago

I think it's even simpler than that. Users (our sales guys) can't make their own models outside what I would program fro them. For example, we may offer plain shaft with no turndowns and shaft with turndown. That's it. I would program model creating in CQ based on their html from input and they would get back 2d view with dimensions.

Thanks

dcowden commented 5 years ago

yeah, i see. you need the same functionality, but it doesnt need to be as generalized.

What if we worked towards getting a docker image that produces the ability to run as a server and provide REST endpoints to build models and give results? then , the steps to do what you want would be to run the cq docker image, and run another nginx server with your static frontend....

On Fri, Apr 26, 2019 at 10:25 AM Shreko notifications@github.com wrote:

I think it's even simpler than that. Users (our sales guys) can't make their own models outside what I would program fro them. For example, we may offer plain shaft with no turndowns and shaft with turndown. That's it. I would program model creating in CQ based on their html from input and they would get back 2d view with dimensions.

Thanks

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/CadQuery/cadquery/issues/122#issuecomment-487076310, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJ44AYAZ22EB7GJBEZ7LB3PSMGGLANCNFSM4HINAE7Q .

shrekuntu commented 5 years ago

Setting up nginx, flask, validation is not a problem. Question is what is the best way to add dimensions to an svg? Something like, we need to know where reference center point of the model is on the svg and what is the scale, so we can find bottom left points of the shaft ends so we can add shaft length dimension below the shaft if that was predetermined location of the shaft length dim.

Or even better, if we could name some points in in the model, for example for shaft 3" dia x 44" long, "bottom left" would be (-22,-1.5) in XY, and then if SVG export could somehow mark these points, it would be easier to add dimension entities.

jmwright commented 5 years ago

@shrekuntu Marking of features is something that we've discussed in the past, but CQ is not capable of it currently. The move away from FreeCAD to PythonOCC should enable it though. Our SVG exporter already adds an origin marker to the SVG text in the file.

If you are able to figure out a way to translate between the model coordinates and the SVG coordinates, the SVG exporter could be modified to append arbitrary SVG strings, allowing you to add generated dimensions. I suspect that this region of code is a good place to start poking around with this idea:

https://github.com/CadQuery/cadquery/blob/master/cadquery/occ_impl/exporters.py#L364

SamuelReynolds commented 4 years ago

Thinking aloud here...

A 2-D engineering drawing (front/top/left views) can be seen as simply a projection of a 3-D component onto X-Z, X-Y, and Y-Z planes. An isometric drawing is a view from a specific angle.

An approach for generating these from a model has occurred to me (while I was trying to get plugins to work on a rotated workplane--different issue). Note that this is a rough description (brain dump), and I don't have a handle on the CadQuery internals.

The approach is to (1) add annotations at the point where they apply, then (2) render them to "3-D" text at a later point using an annotation "context" tag. The 2-D planar projections would take care of flattening the text appropriately, or it could be "floated" in an isometric or other "3-D" projection.

A new method CQ.annotate accepts the following parameters and stores them on the current CQ object...

  • context - label or list of labels to be referenced at rendering/presentation time
  • atype - annotation type (dimension, note, centerline, ???)
  • label - label text 'context' would be one or more user-defined labels, such as "view.front", "view.left", "view.isometric".

Another new method CQ.render_annotations (or a function render_with_annotations) accepts one or more context labels (e.g., "front_view", "motor_notes"). It walks the stack and finds only the objects that are tagged with the specified annotation context(s). It computes and adds any necessary extension, center, and dimension lines and the corresponding labels and renders them into the model.

If .render_annotations(...) is not called, exporters ignore/discard the annotation information.

For a top/front/side 2-D engineering drawing, one would create the model, then call .render_annotations(...) (or .render_with_annotations(...)) three times, once for each view.

Rendering annotations into the model means that only one layout "engine" is required. However, instead of rendering annotations into the model, it could be left up to the exporter(s) how to render the annotations.

shrekuntu commented 4 years ago

It's been more than a year since my original post here, I haven't given up on this yet. Could there be a way for CQ to export views to dxf. Then we could use ezdxf to add dimensions, and from what I can see from development branch of ezdxf, there will soon be a Drawing/Export add-on which will be able to export to pdf/svg

adam-urbanczyk commented 4 years ago

There is no DXF export (yet), but we do have preliminary DXF import: https://github.com/CadQuery/cadquery/blob/56046ef9dc0527c6bc9048b950858a2784be6cd7/cadquery/occ_impl/importers.py#L145 Exporting would have similar structure as the code above. There is also section operation, so you can easily generate cross-sections. It'd be great if you would be willing to contribute some code to CQ.

shrekuntu commented 4 years ago

I would have to learn python first as I'm mostly doing ruby/js. I'll see what I can do after some studying of CQ and ezdxf codebases. I'm sure you guys are in the same boat, CQ is not your only project, you have families and day only has 24 hours.

adam-urbanczyk commented 3 years ago

@shrekuntu current master (and the coming 2.1 release) has DXF export (it uses exdxf internally BTW). Still without dimensions though.

shrekuntu commented 3 years ago

Thanks for the update. I've been following cq code a bit and noticed that there is code for dxf export. I am not sure if this code covers full projection to a plane, or just section (cross-section)? I tried once before to project views to dxf, but ran into a bit of a problem with projecting shaft radius fillet to arcs, it wasn't consistent in giving me the arc, in some views it would project to a full circle or something like that. I was using export svg as a ref. guide. Dimensions are not an problem. Will have to track points on the projection and do them in ezdxf. Thanks for your hard work on this.

adam-urbanczyk commented 3 years ago

Currently you need to use .section() in order to export to DXF.

adam-urbanczyk commented 2 years ago

In principle one can use https://github.com/gumyr/cq_warehouse and SVG export to get 2D drawings with dimensions.

tanius commented 2 years ago

For what it's worth, here is a manual process that allowed me to create 2D and 3D drawings with dimensions from CadQuery designs:

  1. Export your CadQuery design to STEP format.
  2. Open the STEP file in FreeCAD.
  3. Switch to the TechDraw workbench in FreeCAD.
  4. Create a page via menu entry "TechDraw → Insert new Page using Template", then choosing a predefined or custom template. (I use a custom blank page template.)
  5. Add dimensions to a TechDraw page's views. That is possible without issues in FreeCAD, including in the 3D views.
  6. Keeping the view updated seems still buggy in FreeCAD. But note that there is an option "Toggle keep updated" available in the context menu of tech drawings, which may help.
  7. Finally export everything via "TechDraw → Export page as SVG".
  8. If necessary, post-process the exported file in an SVG editor such as Inkscape.

I had designed a flat sheet metal part alongside a corresponding 3D part in CadQuery, and now wanted to print the sheet metal part's outline on label paper to cut it. For that, a manual process was fine … if you need to automate this, note that FreeCad has scripting capabilities, but I don't know if and how they would suffice to add required dimensions.

Gigahawk commented 1 year ago

Probably a long way off, but I'm imagining a way to do this within cadquery to be:

  • A new Drawing() class that can consume Workplane.section() objects
  • You can use selectors to select features of the section view (maybe even tagged workplaces from the original part?), then add a dimension (may have to specify the direction and length of the extension line etc), and optionally specify tolerance.
  • Drawing should have definitions for paper size, title block, etc.

Once done, the whole thing can be exported to PDF so that drawings can automatically be updated with dimension/design changes etc.

jmwright commented 1 year ago

I'm adding this link to the documentation for cq_warehouse that may be related. @gumyr might have some thoughts as well.

bertvanbrakel commented 1 year ago

How about just generating two files? One the render, another one with the render and dimension text. Be the same code run, just in one , an 'include_dimensions' flag is set, and this would draw additional objects. These additional object would be the text.

Or two python files, one the model, another the engineering drawing dimensions and text. Then merge the resulting SVG files

MadScrewdriver commented 1 year ago

@shrekuntu, there's a Python package called qsketchmetric that introduces parametric 2D DXF features, of which I am the author. Parametrization and rendering are both very straightforward. I believe it might address the issue.

If anyone requires assistance or specific features, I'm open to collaboration.