Hello.
I have a project where I get an .stl file containing an object which consists of several joined cylinders. Is there a way with KernelCAD to convert it to a parametric object so I can adjust its shape?
Thank you
Reverse engineering surface of revolution
Re: Reverse engineering surface of revolution
Hi Grady
Are the cylinders aligned or coaxial?
We do not have a generic functionality for that, but in this special case there are ways to get a pretty good result. More after your answer
Regards
Are the cylinders aligned or coaxial?
We do not have a generic functionality for that, but in this special case there are ways to get a pretty good result. More after your answer
Regards
Re: Reverse engineering surface of revolution
Hi Nick
Thank you for the answer.
The cylinders are on the same z axis. Diameters are decreasing along z
Looking forward for more
Thank you for the answer.
The cylinders are on the same z axis. Diameters are decreasing along z
Looking forward for more
Re: Reverse engineering surface of revolution
This should be simple
The main thing is to obtain the diameters and lengths of each section.
- List all vertices in the mesh. See Morph sample for an example
- Convert them to pairs (z, d) = (z, distance to z axis). All these points will define profile of the target SOR
- determine max d in the set. Lets call it dm
- Extract subset of points which have d=dm, with some tolerance like 1e-2 to make it stable.
- Range of z for the extracted pairs is the z range of the first section with max diameter
At this point you have identified parameters of the first section
- Remove from the original set of pairs points which belong to the z range.
At his point you have a reduced set with the largest section removed
- Go to the first step
......
This algorithm will work when diameters are not sorted also
For more general case when the axis is different from z axis, but still all coaxial, you need to determine the axis.
Use the precise oriented bounding box the way it is done in Cloud sample. The box will have x and y dimensions the same and equal to the largest diameter. Otherwise your assumptions about the object are wrong.
Query IFrame_DG out of the box and use IFrame_DG.ToLocal() to convert coordinates of all vertices to the local frame. After that you will have the initial case of z being the axis. Go the above steps. When you constructed the SOR set its frame to the frame of the box.
In the most generic case when sections are not aligned you will probably need to extract individual sections as shown in MeshMods sample > Tools > extract using a box extraction proximity
The main thing is to obtain the diameters and lengths of each section.
- List all vertices in the mesh. See Morph sample for an example
- Convert them to pairs (z, d) = (z, distance to z axis). All these points will define profile of the target SOR
- determine max d in the set. Lets call it dm
- Extract subset of points which have d=dm, with some tolerance like 1e-2 to make it stable.
- Range of z for the extracted pairs is the z range of the first section with max diameter
At this point you have identified parameters of the first section
- Remove from the original set of pairs points which belong to the z range.
At his point you have a reduced set with the largest section removed
- Go to the first step
......
This algorithm will work when diameters are not sorted also
For more general case when the axis is different from z axis, but still all coaxial, you need to determine the axis.
Use the precise oriented bounding box the way it is done in Cloud sample. The box will have x and y dimensions the same and equal to the largest diameter. Otherwise your assumptions about the object are wrong.
Query IFrame_DG out of the box and use IFrame_DG.ToLocal() to convert coordinates of all vertices to the local frame. After that you will have the initial case of z being the axis. Go the above steps. When you constructed the SOR set its frame to the frame of the box.
In the most generic case when sections are not aligned you will probably need to extract individual sections as shown in MeshMods sample > Tools > extract using a box extraction proximity
Re: Reverse engineering surface of revolution
Thank you, Nick
I see it is the method for reading the required parameters. What is the good way to build the actual object?
Thank You
I see it is the method for reading the required parameters. What is the good way to build the actual object?
Thank You
Re: Reverse engineering surface of revolution
The simplest way is to create a new cylinder using IStdShape_DG.Cylinder() http://www.dynoinsight.com/Help/V6_0/In ... x#Cylinder for each section separately. It is oriented correctly by default.
You need to add the new objects to the model to have it in the scene:
You can shift second and following sections along z via:
IFrame_DG iFr = section.GetLocation();
iFr.Translate1(0, 0, sum of previous lengthes);
It is better to group the sections either by adding second etc. to the first one with IEntity_DG.AddChild() or create an empty group entity via:
Mesh is just the min overhead type. Can be any type because not adding anything to its geometry here
There is also an option to create the whole thing as a single object. Tomorrow about that
Cheers
You need to add the new objects to the model to have it in the scene:
Code: Select all
IModel_DG iModel = (IModel_DG)theControl.GetModel();
IStdShape_DG iStdSh = iModel as IStdShape_DG;
IEntity_DG section = iStdSh.Cylinder(radius, radius, lenght);
iModel.AddEntity(section)
IFrame_DG iFr = section.GetLocation();
iFr.Translate1(0, 0, sum of previous lengthes);
It is better to group the sections either by adding second etc. to the first one with IEntity_DG.AddChild() or create an empty group entity via:
Code: Select all
IEntity_DG group = iModel.AddNewEntity2("Mesh");
...
group.AddChild(section);
There is also an option to create the whole thing as a single object. Tomorrow about that
Cheers
Re: Reverse engineering surface of revolution
To make a single object SOR you would need to use KC interface:
- Query IStdShape from IModel_DG or IModel.
- Call IStdShape.Cylinder(double baseRadius, double topRadius, double height, ISection** cylinder), which will return ISection* cylinder
- Query cylinder > IStrip > IStripTopol
- Use IStripTopol.Add(z, rad, true) to extend the 2D generatrix which consist of segments in the case
You will need to add the vertical segments between the sections and the last closing one: IStripTopol.Add(total_length, 0.0, true)
See http://www.dynoinsight.com/Help/V6_0/De ... R/SOR.aspx for more
Any questions are welcome
- Query IStdShape from IModel_DG or IModel.
- Call IStdShape.Cylinder(double baseRadius, double topRadius, double height, ISection** cylinder), which will return ISection* cylinder
- Query cylinder > IStrip > IStripTopol
- Use IStripTopol.Add(z, rad, true) to extend the 2D generatrix which consist of segments in the case
You will need to add the vertical segments between the sections and the last closing one: IStripTopol.Add(total_length, 0.0, true)
See http://www.dynoinsight.com/Help/V6_0/De ... R/SOR.aspx for more
Any questions are welcome