Author Topic: How to align ucs with solid in C#  (Read 1750 times)

0 Members and 1 Guest are viewing this topic.

MickD

  • Gator
  • Posts: 3306
  • (x-in)->[process]->(y-out)
Re: How to align ucs with solid in C#
« Reply #15 on: December 11, 2018, 04:32:38 AM »
There really is no easy way to do this by 'inspection'. Even if you pick the longest edge for length say, you may have grain/pattern direction of the finished surface to deal with. There are many other edge cases as well. MillLister/SmartLister (cabinet making material lister) came the closest but then you still needed to check the length/width/height directions and edit them if not quite right for purpose.

Storing world point xdata upon creation is the easiest solution even if you have to add it manually for old models. The beauty is if you move, edit or copy the object the data goes and gets updated with it. I spent many hours on this in the past (even inspecting BREP in C++ before C# came along) and apart from creating a 'custom object' this is the easiest solution IMO.
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

SEANT

  • Bull Frog
  • Posts: 324
Re: How to align ucs with solid in C#
« Reply #16 on: December 11, 2018, 06:05:28 AM »
This ‘Solid Dimensions’ conundrum has been debated numerous times before.  As a matter of fact, it seems to crop up every other year like clockwork. 

And, as has been mentioned before, some of the programming options will be based on the level of control a programmer has over the workflow used during the ‘digital mass’ creation.

If the ‘non- workflowed’ files containing old models are of sufficient mass, the “. . . . Storing world point xdata upon creation is the easiest solution even if you have to add it manually for old models . . . .”  could be rather daunting. 

What might help is a routine that could pre-process the mass to find a most likely orientation. 8-)
Sean Tessier
AutoCAD 2016 Mechanical

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: How to align ucs with solid in C#
« Reply #17 on: December 11, 2018, 07:48:11 AM »
SmartLister (cabinet making material lister)

Hey, I remember them, Dave right?  They did good work  8-)

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: How to align ucs with solid in C#
« Reply #18 on: December 11, 2018, 08:10:55 AM »
This ‘Solid Dimensions’ conundrum has been debated numerous times before...

like this thread?
https://www.theswamp.org/index.php?topic=24045.0

MickD

  • Gator
  • Posts: 3306
  • (x-in)->[process]->(y-out)
Re: How to align ucs with solid in C#
« Reply #19 on: December 11, 2018, 03:27:36 PM »
SmartLister (cabinet making material lister)

Hey, I remember them, Dave right?  They did good work  8-)

Yep, that's the one :)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

MickD

  • Gator
  • Posts: 3306
  • (x-in)->[process]->(y-out)
Re: How to align ucs with solid in C#
« Reply #20 on: December 11, 2018, 03:38:36 PM »
This ‘Solid Dimensions’ conundrum has been debated numerous times before.  As a matter of fact, it seems to crop up every other year like clockwork. 

And, as has been mentioned before, some of the programming options will be based on the level of control a programmer has over the workflow used during the ‘digital mass’ creation.

If the ‘non- workflowed’ files containing old models are of sufficient mass, the “. . . . Storing world point xdata upon creation is the easiest solution even if you have to add it manually for old models . . . .”  could be rather daunting

What might help is a routine that could pre-process the mass to find a most likely orientation. 8-)

IDK, the pre-processing solids sounds more daunting to me :)
I'll see if I can dig out my old code to add the xdata at creation and for retro fit, be back a bit later :)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

MickD

  • Gator
  • Posts: 3306
  • (x-in)->[process]->(y-out)
Re: How to align ucs with solid in C#
« Reply #21 on: December 11, 2018, 05:05:34 PM »
Here's some snippets of the types of data I add to the 3d solid at creation time, this is part of a much larger class that holds a 3dSolid (_solid) as a private property and the x, y, z values etc as class properties, these can be calculated and set from the polyline plane and normal or however you want to calculate your ECS. I use the extrusion direction and/or normal of the polyline I'm about to extrude.
Just remember to normalise the vectors to make it easier later.

Hopefully it's a good starting point for someone :)

Code - C#: [Select]
  1.                 public void SetXData()
  2.                 {
  3.      // check for xdata app name
  4.                         if(Utils.CheckForAppName())
  5.                         {
  6.                                 ResultBuffer resbuf = new ResultBuffer();
  7.                                 Point3d pntL = new Point3d(_start.X,_start.Y,_start.Z);
  8.                                 Point3d pntR = new Point3d(_end.X,_end.Y,_end.Z);
  9.                                 Point3d pntX = new Point3d(_vecX.X,_vecX.Y,_vecX.Z);
  10.                                 Point3d pntY = new Point3d(_vecY.X,_vecY.Y,_vecY.Z);
  11.                                 Point3d pntZ = new Point3d(_vecZ.X,_vecZ.Y,_vecZ.Z);
  12.                                 resbuf.Add(new TypedValue(1001, "MY_APPNAME"));
  13.                                 resbuf.Add(new TypedValue(1011,pntL));
  14.                                 resbuf.Add(new TypedValue(1011,pntR));
  15.                                 resbuf.Add(new TypedValue(1013,pntX)); // world 3D point data types
  16.                                 resbuf.Add(new TypedValue(1013,pntY)); // these get updated
  17.                                 resbuf.Add(new TypedValue(1013,pntZ)); // with modifications
  18.                                 _solid.XData = resbuf;
  19.                         }
  20.  
  21.                         else
  22.                         {
  23.                                 Utils.PrintMessage("\nFailed to add xdata!..");
  24.                         }
  25.                
  26.                 }
  27.  

And a bit of a hack to get the data back into a hash table to make it easier to consume, once you have this you can transform the solid to get the bounding box and length (code below)

Code - C#: [Select]
  1.                 private void GetXdata()
  2.                 {
  3.                         ResultBuffer rb = new ResultBuffer();
  4.                         rb = (ResultBuffer)_solid.GetXDataForApplication("MY__APPNAME");
  5.                         if(rb != null)
  6.                         {
  7.                                 Hashtable ht = new Hashtable();
  8.                                 IEnumerator iter = rb.GetEnumerator();
  9.                                 int i = 0; //count for ht
  10.                                 while (iter.MoveNext())
  11.                                 {
  12.                                         TypedValue tv = (TypedValue)iter.Current;
  13.                                         ht.Add(i,tv.Value);
  14.                                         i++;           
  15.                                 }
  16.                                 //set the property values
  17.                                 Point3d x = new Point3d();
  18.                                 Point3d y = new Point3d();
  19.                                 Point3d z = new Point3d();
  20.                                 Point3d L = new Point3d();
  21.                                 Point3d R = new Point3d();
  22.                                 L = (Point3d)ht[1]; // left end
  23.                                 R = (Point3d)ht[2]; // right end
  24.                                 x = (Point3d)ht[3];
  25.                                 y = (Point3d)ht[4];
  26.                                 z = (Point3d)ht[5];
  27.                                 _start = L; // class properties...
  28.                                 _end = R;
  29.                                 _vecX = new Vector3d(x.X,x.Y,x.Z);
  30.                                 _vecY = new Vector3d(y.X,y.Y,y.Z);
  31.                                 _vecZ = new Vector3d(z.X,z.Y,z.Z);
  32.                         }
  33.                
  34.                 }
  35.  

The _solid is a property of my 3dSolid class and the vectors are set using the code above:
Code - C#: [Select]
  1.                 private double GetLength()
  2.                 {
  3.                         Matrix3d mat = new Matrix3d();
  4.                         Plane plane = new Plane(new Point3d(0,0,0), _vecZ);
  5.                         mat = Matrix3d.WorldToPlane(plane); // transform solid from current position to WCS
  6.                         _solid.TransformBy(mat);
  7.                         double length = _solid.GeometricExtents.MaxPoint.Z - _solid.GeometricExtents.MinPoint.Z;
  8.                         _solid.TransformBy(mat.Inverse()); // transform it back
  9.                         return length;
  10.                 }
  11.  

Here's some code to add xdata to existing solids.

Code - C#: [Select]
  1.                 public static ResultBuffer SetCustomData()
  2.                 {
  3.                         Database db = HostApplicationServices.WorkingDatabase;
  4.                         Editor ed = Bricscad.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
  5.  
  6.                         PromptPointResult pntOri = ed.GetPoint("\nPick 3 points of primary face/view:\nPick origin point(bottom left):");
  7.                         if(pntOri.Status != PromptStatus.OK || pntOri.Status == PromptStatus.Cancel)
  8.                                 return null;
  9.  
  10.                         PromptPointResult pnt2 = ed.GetPoint("\nPick point in 'X' direction of face/view:");
  11.                         if(pnt2.Status != PromptStatus.OK || pnt2.Status == PromptStatus.Cancel)
  12.                                 return null;
  13.  
  14.                         PromptPointResult pnt3 = ed.GetPoint("\nPick point in 'Y' direction of face/view:");
  15.                         if(pnt3.Status != PromptStatus.OK || pnt3.Status == PromptStatus.Cancel)
  16.                                 return null;
  17.  
  18.                         Point3d or = new Point3d();
  19.                         Point3d X = new Point3d();
  20.                         Point3d Y = new Point3d();
  21.                         or = Utils.UcsToWcs(pntOri.Value);
  22.                         X = Utils.UcsToWcs(pnt2.Value);
  23.                         Y = Utils.UcsToWcs(pnt3.Value);
  24.  
  25.                         Vector3d vecx = new Vector3d();
  26.                         Vector3d vecy = new Vector3d();
  27.                         Vector3d vecz = new Vector3d();
  28.  
  29.                         vecz = or.GetVectorTo(X).GetNormal(Tolerance.Global);
  30.                         vecy = or.GetVectorTo(Y);
  31.                         vecx = vecz.CrossProduct(vecy).GetNormal(Tolerance.Global);
  32.                         vecy = vecx.CrossProduct(vecz).GetNormal(Tolerance.Global);
  33.  
  34.                         if(Utils.CheckForAppName())
  35.                         {
  36.                                 ResultBuffer resbuf = new ResultBuffer();
  37.                         {
  38.                                 Point3d pntL = new Point3d(or.X,or.Y,or.Z);
  39.                                 Point3d pntR = new Point3d(X.X,X.Y,X.Z);
  40.                                 Point3d pntX = new Point3d(vecx.X,vecx.Y,vecx.Z);
  41.                                 Point3d pntY = new Point3d(vecy.X,vecy.Y,vecy.Z);
  42.                                 Point3d pntZ = new Point3d(vecz.X,vecz.Y,vecz.Z);
  43.                                 resbuf.Add(new TypedValue(1001,Utils.AppName));
  44.                                 resbuf.Add(new TypedValue(1011,pntL));
  45.                                 resbuf.Add(new TypedValue(1011,pntR));
  46.                                 resbuf.Add(new TypedValue(1013,pntX));
  47.                                 resbuf.Add(new TypedValue(1013,pntY));
  48.                                 resbuf.Add(new TypedValue(1013,pntZ));
  49.                         }
  50.                                
  51.                                 return resbuf;
  52.                         }
  53.                         else
  54.                         {
  55.                                 Utils.PrintMessage("\nFailed to add xdata!..");
  56.                                 return null;
  57.                         }
  58.                
  59.                 }
  60.  

« Last Edit: December 11, 2018, 05:18:52 PM by MickD »
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

kdub

  • Mesozoic relic
  • SuperMod
  • Swamp Rat
  • Posts: 1368
  • class keyThumper<T>:ILazy<T>
Re: How to align ucs with solid in C#
« Reply #22 on: December 11, 2018, 11:14:00 PM »
Hi Mick,

I can sort of visualise how that fitted into your work process.

I assume you'd add component description/catalog at the same time.

It would make material take-off a little simpler.

Stay well.
called Kerry in my other life

Sometimes the question is more important than the answer.
#ridesober

MickD

  • Gator
  • Posts: 3306
  • (x-in)->[process]->(y-out)
Re: How to align ucs with solid in C#
« Reply #23 on: December 11, 2018, 11:30:45 PM »
Hi Mick,

I can sort of visualise how that fitted into your work process.

I assume you'd add component description/catalog at the same time.

It would make material take-off a little simpler.

Stay well.

Yes, you got it Kerry, I quickly stripped out the extraneous stuff like section and item numbers etc. I used an Access DB for section profile data and created solids from 2 points, lines or from profiles from plates. I'd use the code above along with the line/2 points picked and current UCS to build my ECS data and add it to the solid.
I haven't used this code for quite a while now but might dig it out for an update, I think I've held back as I wanted to convert the DB to an SQLite setup as the Access drivers are well dated now.

I also used the ECS data with the 2D engine I built to automatically create drawings and matlists, it worked pretty well for stock solid modelling. Bricscad has come a long way since then and I don't think it's needed anymore :)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

johnpolob

  • Newt
  • Posts: 29
Re: How to align ucs with solid in C#
« Reply #24 on: December 12, 2018, 04:57:00 AM »
Hi everybody,
Thank you all for your ideas and solutions.
I still gave up my last idea and I'm stuck here.
I have another idea but I do not know if I can implement it.
The idea is to make sure that all my solids are in the same plane and then I can measure them.
Could someone have an example for this kind of case?
Need your help.

SEANT

  • Bull Frog
  • Posts: 324
Re: How to align ucs with solid in C#
« Reply #25 on: December 12, 2018, 05:51:47 AM »
Hi everybody,
Thank you all for your ideas and solutions.
I still gave up my last idea and I'm stuck here.
I have another idea but I do not know if I can implement it.
The idea is to make sure that all my solids are in the same plane and then I can measure them.
Could someone have an example for this kind of case?
Need your help.

Did the link in nullptr's post (#18) contain anything you can use?
Sean Tessier
AutoCAD 2016 Mechanical

SEANT

  • Bull Frog
  • Posts: 324
Re: How to align ucs with solid in C#
« Reply #26 on: December 12, 2018, 05:57:12 AM »
Here's some snippets of the types of data I add to the 3d solid at creation time, this is part of a much larger class that holds a 3dSolid (_solid) as a private property and the x, y, z values etc as class properties, these can be calculated and set from the polyline plane and normal or however you want to calculate your ECS. I use the extrusion direction and/or normal of the polyline I'm about to extrude.
Just remember to normalise the vectors to make it easier later.

Hopefully it's a good starting point for someone :)


That looks like some highly effective and terse code.  Thank you for sharing.  That is an incredible leg up on the pre-model process methodology.

I’ve got some code prepped for post-model.  Still quite a work in progress – and, certainly, not nearly as terse.  I’ll look it over again in the next few weeks and post the project in whatever state it is in at that point.

I mostly focused on extruded profiles.  The hope was to not only get the lengths, but also some post modeling profile recognition.  So If I knew someone was modeling with the aid of “Al’s Steel Mill”, a type and quantity takeoff could be made by comparing Profile Area, Perimeter, and Moments of Inertia. 

I’m referring to the methodology as POCS (Preponderance of Coordinated Systems).  It’s reasonably effective at recovering extrusion direction.  As can be seen in the screencast, though,  the profile recognition still needs some work.

https://autode.sk/2Bmfkjp
Sean Tessier
AutoCAD 2016 Mechanical

johnpolob

  • Newt
  • Posts: 29
Re: How to align ucs with solid in C#
« Reply #27 on: December 12, 2018, 06:02:19 AM »
Hi SEANT,

Thank you for the link.

I never saw It when I wrote down my last idea.

At first, It could help me.

I will try to test It and let you know.

Thank you very much...

johnpolob

  • Newt
  • Posts: 29
Re: How to align ucs with solid in C#
« Reply #28 on: December 12, 2018, 06:16:29 AM »
Hi MickD,

Thank you very much for your contribution.

I am working on It.

MickD

  • Gator
  • Posts: 3306
  • (x-in)->[process]->(y-out)
Re: How to align ucs with solid in C#
« Reply #29 on: December 13, 2018, 12:34:19 AM »

I mostly focused on extruded profiles.  The hope was to not only get the lengths, but also some post modeling profile recognition.  So If I knew someone was modeling with the aid of “Al’s Steel Mill”, a type and quantity takeoff could be made by comparing Profile Area, Perimeter, and Moments of Inertia. 


Yep, my code is focused more on the pre-modelling as you say and I only work with extrusions of steel profiles and plates. Not shown in the code is the extra data I add such as section profile data, weight calculations (which takes cuts and holes into consideration), surface area etc. The standard section data is added at creation and lengths and weights are added/updated during processing for material lists etc.

The reason I gave up on trying to get LWH from existing solids is I knew that practically all my new work would be created using my tools which made things a lot easier. What would have made my tools really good was to make an 'auto-numbering' tool, this was the weak link in my workflow otherwise I could model a steel job just as quick as a more professional detailing package.
Auto dimensions would also have been nice and  I had plans for that too...just not enough free time to do it :)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”