Author Topic: Creating 3D Text and Wrap it Around a Pipe (Cylinder)  (Read 1941 times)

0 Members and 1 Guest are viewing this topic.

MickD

  • Gator
  • Posts: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #15 on: May 11, 2020, 07:00:47 PM »
It looks very close! Without knowing what the actual ECS vectors represent on the pipe you may need to experiment. Try changing the ECS vectors, what we have at the moment is the WCS Xvector aligning with the ECS Xvector but that is assuming the ECS Xvector is the pipe centreline, the ECS zVector may be that direction.

You're nearly there :) Maybe if you have time you can programatically draw some lines to represent the ECS, color each the same as the WCS (x=red, y=green, z=blue). To do this, use the ECS origin as the start point, scale the pipeEcs.Xaxis * someAmount to give it a length in that direction and the second point of the line. Do the same for each axis.

If I get time today I'll try to mock something up.

p.s.
just looking at the text at pipe, it looks like the ECS origin is at the centre of the pipe, the Zaxis is pointing along the pipe towards the top of image and Xaxis is going out from the pipe to the right. Swap the origin for pipe start point, the Xaxis with ECS.Zaxis then play with the last one to fine tune direction/rotation around the pipe.
hth

p.p.s.
sorry just re-read your last paragraph and I had the cylinder confused with the pipe.
You are creating the text along the WCS Xaxis (it seems), when creating a cylinder it creates them along the Zaxis so you will need to rotate the cylinder to the text before moving it to the pipe.
I can't find anything in the doc's to tell us just what the ECS represents on the plant3d pipe so if you can I'd draw the ECS as mentioned above, I'll be back with some code for that shortly :)
« Last Edit: May 11, 2020, 07:37:24 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.”

MickD

  • Gator
  • Posts: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #16 on: May 11, 2020, 08:16:14 PM »
here's a standalone sample of drawing an ECS on a pipe say, I'm using the WCS as example matrix here but you need to pass in your pipe ECS. This will give you a better idea of what's going on hopefully :)

Code - C#: [Select]
  1. // change below for AutoCAD
  2. using Bricscad.ApplicationServices;
  3. using Teigha.DatabaseServices;
  4. using Teigha.Geometry;
  5. using Teigha.Runtime;
  6.  
  7. namespace swamper
  8. {
  9.     public class Commands
  10.     {
  11.         public static void PostToDatabase(Entity entity)
  12.         {
  13.             Document doc = Application.DocumentManager.MdiActiveDocument;
  14.             Database db = doc.Database;
  15.  
  16.             using (Transaction tr = db.TransactionManager.StartTransaction())
  17.             {
  18.                 BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  19.                 BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  20.  
  21.                 btr.AppendEntity(entity);
  22.                 tr.AddNewlyCreatedDBObject(entity, true);
  23.  
  24.                 tr.Commit();
  25.             }
  26.         }
  27.  
  28.         public static void DrawPipeEcsAxes(Matrix3d pipeEcs)
  29.         {
  30.             Point3d origin = pipeEcs.CoordinateSystem3d.Origin;
  31.             // create xvec and give it length:
  32.             Vector3d xvec = pipeEcs.CoordinateSystem3d.Xaxis;
  33.             xvec = xvec.MultiplyBy(10); // this is 10mm for me, maybe 10 inches for you??
  34.             Line xaxis = new Line(origin, new Point3d(xvec.X, xvec.Y, xvec.Z));
  35.             xaxis.ColorIndex = 1;
  36.             PostToDatabase(xaxis);
  37.  
  38.             // create yvec and give it length:            
  39.             Vector3d yvec = pipeEcs.CoordinateSystem3d.Yaxis;
  40.             yvec = yvec.MultiplyBy(10);
  41.             Line yaxis = new Line(origin, new Point3d(yvec.X, yvec.Y, yvec.Z));
  42.             yaxis.ColorIndex = 100;
  43.             PostToDatabase(yaxis);
  44.  
  45.             // create zvec and give it length:
  46.             Vector3d zvec = pipeEcs.CoordinateSystem3d.Zaxis;
  47.             zvec = zvec.MultiplyBy(10);
  48.             Line zaxis = new Line(origin, new Point3d(zvec.X, zvec.Y, zvec.Z));
  49.             zaxis.ColorIndex = 150;
  50.             PostToDatabase(zaxis);
  51.         }
  52.  
  53.  
  54.         [CommandMethod("pipetext")]
  55.         public static void PipeText()
  56.         {
  57.             // get the pipe ECS here and pass it to our draw function, we are just using the WCS matrix here:
  58.             // drawPipeEcsAxes(myPipe.getEcs());
  59.             DrawPipeEcsAxes(Matrix3d.Identity);
  60.         }
  61.     }
  62. }
  63.  
  64.  
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.”

flyte

  • Newt
  • Posts: 26
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #17 on: May 11, 2020, 09:14:48 PM »
Thanks once again MickD.

As requested, here is the result of using your code to create the vectors of the selected pipe. Like before, the red arrow shows the pipe that I selected. The green box surrounds the text and cylinder that was created. The green arrows shows the start and end of the vectors that are drawn, (start point of pipe, and to origin) In the initial screenshot, they are all on top o each other, but when you zoom in, you can then see the individual vectors.

I hope this helps (?)

MickD

  • Gator
  • Posts: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #18 on: May 11, 2020, 09:28:30 PM »
Ah, ok. It doesn't look like the ECS is very helpful. Can you debug and let me know what the values of the ECS vectors are?
And, how far apart are the 3 new lines and are they parallel?

maybe you can ID the start points of these lines as well please, we may be able to create the ECS with these.

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: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #19 on: May 11, 2020, 09:43:44 PM »

The green arrows shows the start and end of the vectors that are drawn, (start point of pipe, and to origin)

I don't understand why the lines are drawn to origin, did you just pass in the ECS as per function param's?

Also, try using pipe start point as line start points (may need to pass this in as param to function). Whatever you use the lines should only be 'a' units long where 'a' is the amount you multiply the vector by....
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.”

flyte

  • Newt
  • Posts: 26
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #20 on: May 11, 2020, 11:46:32 PM »
Here are the values from the debugger:

Code - C#: [Select]
  1. origin   {(-1986.9832609598,4489.18265730619,0)} // Point3d origin = pipeEcs.CoordinateSystem3d.Origin;
  2. pipeEcs   {((0.999997248002804,0.00234605771834044,0,-1986.9832609598),(-0.00234605771834044,0.999997248002804,0,4489.18265730619),(0,0,1,0),(0,0,0,1))}
  3. xvec   {(9.99997248002804,-0.0234605771834044,0)}      
  4. yvec   {(0.0234605771834044,9.99997248002804,0)}       
  5. zvec   {(0,0,10)}      
  6. this.position   {(-1986.983261,4489.182657,0)} // this is the pipe's start point.      

Hr.m.. very strange that the pipe's start point (this.position) isn't exactly the same as the pipeEcs.CoordinateSystem3d.Origin (or is that normal?)
« Last Edit: May 12, 2020, 12:04:49 AM by flyte »

MickD

  • Gator
  • Posts: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #21 on: May 12, 2020, 12:08:14 AM »
Thanks for that, I came up with a workaround to save us both some time :)

The code below uses a line as your pipe and you will need to change things where commented.

This is fiddly stuff and only by trial and error does it finally click into place, I haven't done this stuff for a while :roll:

Anyway, this will draw the axes on the pipe (hopefully), when it does you know that you can use the code for your text etc, get this working and we'll tackle the text.

Code - C#: [Select]
  1.  
  2. using Bricscad.ApplicationServices;
  3. using Bricscad.EditorInput;
  4. using Teigha.DatabaseServices;
  5. using Teigha.Geometry;
  6. using Teigha.Runtime;
  7.  
  8. namespace swamper
  9. {
  10.     public class Commands
  11.     {
  12.         public static void PostToDatabase(Entity entity)
  13.         {
  14.             Document doc = Application.DocumentManager.MdiActiveDocument;
  15.             Database db = doc.Database;
  16.  
  17.             using (Transaction tr = db.TransactionManager.StartTransaction())
  18.             {
  19.                 BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  20.                 BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  21.  
  22.                 btr.AppendEntity(entity);
  23.                 tr.AddNewlyCreatedDBObject(entity, true);
  24.  
  25.                 tr.Commit();
  26.             }
  27.         }
  28.  
  29.         public static void DrawPipeEcsAxes(Matrix3d pipeEcs)
  30.         {
  31.             /**
  32.              * Note: all points used/aquired are in WCS, this is why we need to
  33.              * transform some of them to our pipe
  34.              */
  35.             // get a vector from the WCS origin to ECS origin to use in displacement later
  36.             var ovec = pipeEcs.CoordinateSystem3d.Origin.GetAsVector();
  37.             Point3d origin = new Point3d(ovec.X, ovec.Y, ovec.Z);
  38.             // create xvec and give it length:
  39.             Vector3d xvec = pipeEcs.CoordinateSystem3d.Xaxis;
  40.             xvec = xvec.MultiplyBy(10); // this is 10mm for me, maybe 10 inches for you??
  41.  
  42.             // NOTE: each of the ECS vectors are directions relative to WCS, we need to move them to the object with TransformBy()
  43.             Line xaxis = new Line(origin, new Point3d(xvec.X, xvec.Y, xvec.Z).TransformBy(Matrix3d.Displacement(ovec)));
  44.             xaxis.ColorIndex = 1;
  45.             PostToDatabase(xaxis);
  46.  
  47.             // create yvec and give it length:            
  48.             Vector3d yvec = pipeEcs.CoordinateSystem3d.Yaxis;
  49.             yvec = yvec.MultiplyBy(10);
  50.             Line yaxis = new Line(origin, new Point3d(yvec.X, yvec.Y, yvec.Z).TransformBy(Matrix3d.Displacement(ovec)));
  51.             yaxis.ColorIndex = 100;
  52.             PostToDatabase(yaxis);
  53.  
  54.             // create zvec and give it length:
  55.             Vector3d zvec = pipeEcs.CoordinateSystem3d.Zaxis;
  56.             zvec = zvec.MultiplyBy(10);
  57.             Line zaxis = new Line(origin, new Point3d(zvec.X, zvec.Y, zvec.Z).TransformBy(Matrix3d.Displacement(ovec)));
  58.             zaxis.ColorIndex = 150;
  59.             PostToDatabase(zaxis);
  60.            
  61.         }
  62.  
  63.  
  64.         [CommandMethod("pipetext")]
  65.         public static void PipeText()
  66.         {
  67.             // get the pipe ECS here and pass it to our draw function, we are just using the WCS matrix here:
  68.             // drawPipeEcsAxes(myPipe.getEcs());
  69.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  70.             var entResult = ed.GetEntity("Select an entity: ");
  71.             if (entResult.Status != PromptStatus.OK) return;
  72.  
  73.             var db = HostApplicationServices.WorkingDatabase;
  74.             using (Transaction tr = db.TransactionManager.StartTransaction())
  75.             {
  76.                 var pipe = tr.GetObject(entResult.ObjectId, OpenMode.ForRead, false) as Line; // as 'myPipe' for your task
  77.                 if(pipe != null)
  78.                 {
  79.                     // replace my 'pipe' stuff with the comments at end of line, it just might work ;)
  80.                     var pipeXaxis = pipe.StartPoint.GetVectorTo(pipe.EndPoint).GetNormal(); // myPipe.Ecs.CoordinateSystem3d.Xaxis
  81.                     var pipeZaxis = pipe.Normal; // myPipe.Ecs.CoordinateSystem3d.Zaxis
  82.                     var pipeYaxis = pipeZaxis.CrossProduct(pipeXaxis); // myPipe.Ecs.CoordinateSystem3d.Yaxis
  83.  
  84.                     // create the new pipeEcs for use in tranformations:
  85.                     var pipeEcs = Matrix3d.AlignCoordinateSystem(
  86.                             // from WCS
  87.                             Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
  88.                             // to ECS
  89.                             pipe.StartPoint, pipeXaxis, pipeYaxis, pipeZaxis
  90.                         );
  91.  
  92.                     DrawPipeEcsAxes(pipeEcs);
  93.                 }
  94.                
  95.                 tr.Commit();
  96.             }
  97.         }
  98.     }
  99. }
  100.  
  101.  
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: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #22 on: May 12, 2020, 12:10:16 AM »
Here are the values from the debugger:

Code - C#: [Select]
  1. origin   {(-1986.9832609598,4489.18265730619,0)} // Point3d origin = pipeEcs.CoordinateSystem3d.Origin;
  2. pipeEcs   {((0.999997248002804,0.00234605771834044,0,-1986.9832609598),(-0.00234605771834044,0.999997248002804,0,4489.18265730619),(0,0,1,0),(0,0,0,1))}
  3. xvec   {(9.99997248002804,-0.0234605771834044,0)}      
  4. yvec   {(0.0234605771834044,9.99997248002804,0)}       
  5. zvec   {(0,0,10)}      
  6. this.position   {(-1986.983261,4489.182657,0)} // this is the pipe's start point.      

Hr.m.. very strange that the pipe's start point (this.position) isn't exactly the same as the pipeEcs.CoordinateSystem3d.Origin (or is that normal?)

I think that is just formatting by the debugger for output, it's close enough :)
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: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #23 on: May 12, 2020, 12:35:33 AM »
this works for me to transform some text from WCS to pipe ECS. Note that I'm drawing text along WCS x axis and my pipe x axis goes from start to end point, you may need to swap these around to suit your pipe ECS but the framework is there.
Sample dwg attached as well for test. Note that I created the line by setting up a ucs first (depicted by the drawn axes) then created the line, this gave me the line's 'normal' in the direction I wanted and was used to create its ECS.

Code - C#: [Select]
  1.             var db = HostApplicationServices.WorkingDatabase;
  2.             using (Transaction tr = db.TransactionManager.StartTransaction())
  3.             {
  4.                 var pipe = tr.GetObject(ent1Result.ObjectId, OpenMode.ForRead, false) as Line; // as 'myPipe' for your task
  5.                 if(pipe != null)
  6.                 {
  7.                     // replace my 'pipe' stuff with the comments at end of line, it just might work ;)
  8.                     var pipeXaxis = pipe.StartPoint.GetVectorTo(pipe.EndPoint).GetNormal(); // myPipe.Ecs.CoordinateSystem3d.Xaxis
  9.                     var pipeZaxis = pipe.Normal; // myPipe.Ecs.CoordinateSystem3d.Zaxis
  10.                     var pipeYaxis = pipeZaxis.CrossProduct(pipeXaxis); // myPipe.Ecs.CoordinateSystem3d.Yaxis
  11.  
  12.                     // create the new pipeEcs for use in tranformations:
  13.                     var pipeEcs = Matrix3d.AlignCoordinateSystem(
  14.                             // from WCS
  15.                             Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
  16.                             // to ECS
  17.                             pipe.StartPoint, pipeXaxis, pipeYaxis, pipeZaxis
  18.                         );
  19.  
  20.                     DrawPipeEcsAxes(pipeEcs);
  21.  
  22.                     // rotate the text to the 'pipe':
  23.                     // open text for write, we need tomove it:
  24.                     var textEntity = tr.GetObject(ent2Result.ObjectId, OpenMode.ForWrite, false) as Entity;
  25.                     if(textEntity != null)
  26.                     {
  27.                         textEntity.TransformBy(pipeEcs);
  28.                     }
  29.                 }
  30.  
  31.                 tr.Commit();
  32.             }
  33.  
« Last Edit: May 12, 2020, 12:55:49 AM 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.”

flyte

  • Newt
  • Posts: 26
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #24 on: May 12, 2020, 01:47:30 AM »
We are getting closer!

So taking your framework, and adjusting it to work with the Pipe (myPipe), and then transforming the text solid with your calculated pipeEcs gives me the text solid in the proper orientation of the pipe. See screenshot - "test1" and "test2" are rendered at the start point of each pipe and it is in the direction of the pipe. I will need to tweak to then move the text to the center point, flip it so that the text is vertical and justified. This is a great win!

But applying that same pipeEcs to the cut-cylinder doesn't appear to properly orientate that. See second screenshot (I manually deleted the cylinders in the first screenshot so you could easily see the text on the pipe).

The code I used to create that pipeEcs is exactly what you instructed me to do in your comments. The resulting code is, (and slightly modified to accept a Pipe as a parameter) is:
Code - C#: [Select]
  1. private static Matrix3d GetPipeEcs(Pipe myPipe)
  2. {
  3.     var pipeXaxis = myPipe.Ecs.CoordinateSystem3d.Xaxis;  // pipe.StartPoint.GetVectorTo(pipe.EndPoint).GetNormal();
  4.     var pipeZaxis = myPipe.Ecs.CoordinateSystem3d.Zaxis;  // pipe.Normal;
  5.     var pipeYaxis = myPipe.Ecs.CoordinateSystem3d.Yaxis;  // pipeZaxis.CrossProduct(pipeXaxis);
  6.  
  7.     return Matrix3d.AlignCoordinateSystem(
  8.         // from WCS
  9.         Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
  10.         // to ECS
  11.         myPipe.StartPoint, pipeXaxis, pipeYaxis, pipeZaxis);
  12. }
  13.  

and the subsequent calls:

Code - C#: [Select]
  1.    
  2. using (Transaction tr = this.m_db.TransactionManager.StartTransaction())
  3. {
  4.     try
  5.     {
  6.         BlockTableRecord btr = tr.GetObject(this.m_db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  7.         ent.SetDatabaseDefaults();
  8.  
  9.         // Extrude this region just beyond the thickness of the pipe...
  10.         var textSolid = new Solid3d { RecordHistory = true };
  11.         textSolid.Extrude(ent as Region, extrudeHeight, 0.0);
  12.  
  13.         // Using ECS
  14.         textSolid.TransformBy(pipeEcs);
  15.  
  16.         btr.AppendEntity(textSolid);
  17.         tr.AddNewlyCreatedDBObject(textSolid, true);
  18.        
  19.         // Create the cylinder that will be subtracted from the text region, and move it to the center point of the pipe..
  20.         var cyl = new Solid3d { RecordHistory = true };
  21.         var radius = (outsideDiameter / 2.0);
  22.         cyl.CreateFrustum(pipeLength, radius, radius, radius);
  23.         cyl.TransformBy(pipeEcs);
  24.         btr.AppendEntity(cyl);
  25.         tr.AddNewlyCreatedDBObject(cyl, true);
  26.     }
  27.  
  28.     catch
  29.     {
  30.         this.m_isValid = false;
  31.     }
  32.  
  33.     finally
  34.     {
  35.         tr.Commit();
  36.     }
  37. }
  38.  

Any ideas on why the cylinder didn't orientate like the text solid did?

MickD

  • Gator
  • Posts: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #25 on: May 12, 2020, 02:28:33 AM »
Cool!

Yes, you will need to tweak the text position algorithm to suit pipe sizes etc.

Your cylinder is created in WCS and the normal to extrude along is probably the ZAxis.
You can either rotate your cylinder to the text first then transform it to the pipe or you can create a circle at the text start point, set the normal to Vector3d.XAxis (to extrude along text xAxis) and Extrude() with a height to be just longer than the text. Extrude will need and use the region (created from the circle) normal as the extrusion direction ;)

to create the region: (you may be able to just 'circle as Region' but I use the collections incase I want to make things like pipes, RHS etc.)
Code - C#: [Select]
  1. DBObjectCollection colPoly = new DBObjectCollection();
  2. DBObjectCollection colregion = new DBObjectCollection();
  3. Region region = new Region();
  4.  
  5. var diameter = myPipe.Diameter; // or similar
  6. Circle circle = new Circle(new Point3d(),Vector3d.XAxis,diameter); // create circle at origin
  7. colPoly.Add(circle);
  8. colregion = Region.CreateFromCurves(colPoly);
  9. region = (Region)colregion[0];
  10.  

I'd create and subtract the cylinder and text before transforming the 'etching' text to the pipe.
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: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #26 on: May 12, 2020, 02:33:39 AM »
p.s. do as much tweaking of text and cutting cylinder in WCS before moving the cutting text to pipe, it's easier on your brain ;)
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.”

flyte

  • Newt
  • Posts: 26
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #27 on: May 13, 2020, 09:51:40 PM »
...closer still...

Quote
You can either rotate your cylinder to the text first then transform it to the pipe
I couldn't figure this out, .. I could move it to the start point of the pipe just fine, but couldn't figure out the transform / rotation to get it to align with the pipe. So then I tried:

Quote
or you can create a circle at the text start point, set the normal to Vector3d.XAxis (to extrude along text xAxis) and Extrude() with a height to be just longer than the text

Which led me to this code:

Code - C#: [Select]
  1. var textSolid = textConverter.ConstructTextSolid();
  2. if (textSolid == null)
  3.         return;
  4.  
  5. textSolid.TransformBy(pipeEcs);
  6.  
  7. btr.AppendEntity(textSolid);
  8. tr.AddNewlyCreatedDBObject(textSolid, true);
  9.  
  10. // Create the subtraction cylinder...
  11. var pipeStart = pipe.StartPoint;
  12. var pipeVector = pipeStart.GetVectorTo(pipe.EndPoint);
  13. double pipeRadius = outsideDiameter / 2.0;
  14.  
  15. var circle = new Circle(pipe.StartPoint, pipeVector, pipeRadius);
  16. btr.AppendEntity(circle);
  17. tr.AddNewlyCreatedDBObject(circle, true);
  18.  
  19. var regs = new DBObjectCollection { circle };
  20. var regions = new DBObjectCollection();
  21. regions = Region.CreateFromCurves(regs);
  22. var reg = (Region)regions[0];
  23.  
  24. var cyl = new Solid3d
  25. {
  26.         RecordHistory = true,
  27.         ShowHistory = true
  28. };
  29. cyl.Extrude(reg, pipeLength, 0.0);
  30.  
  31. btr.AppendEntity(cyl);
  32. tr.AddNewlyCreatedDBObject(cyl, true);
  33.  
  34. textSolid.BooleanOperation(BooleanOperationType.BoolSubtract, cyl);
  35.  
  36. // erase the circle - is this needed??
  37. if (!circle.IsWriteEnabled)
  38.         circle.UpgradeOpen();
  39. circle.Erase();
  40.  
  41. tr.Commit();

and I got interesting results. So the "cylinder" did seem to get created in the proper orientation as the pipe (yay!) See first screenshot.. the red arrow points to the pipe, and the green arrow points to the cut-cylinder solid.

In the second screenshot I deleted the pipe so you can the see just the text solid and cut-cylinder solid.

But as you can see from the third screenshot, the text solid didn't seem to have the cylinder subtracted from it, and I have no idea why..

I think we are very close!

MickD

  • Gator
  • Posts: 3410
  • (x-in)->[process]->(y-out)
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #28 on: May 13, 2020, 10:18:29 PM »
looking good :)

I have no idea why it's not doing the subtraction, all I can think of is maybe you need to Commit() a transaction each time you add the new entities to the db, use my PostToDatabase code for each entity instead perhaps?

Maybe you need to UpgradeOpen the text object as well although you'd think it would cause an exception trying to work on a readonly entity...
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.”

flyte

  • Newt
  • Posts: 26
Re: Creating 3D Text and Wrap it Around a Pipe (Cylinder)
« Reply #29 on: May 15, 2020, 12:28:03 AM »
So I'm not sure what is going on. I tried what you suggested by committing everytime I add the entity to the DB by using the PostToDataBase method, but I have the same results. However, when I do my original approach of creating the cut-cylinder, (which I can't figure out how to orientate it to the pipe), it successfully cuts the text as we saw in an earlier screenshot, (now included in this post as the first screenshot)

Code - C#: [Select]
  1. //
  2. // This method of creating the cylinder works (i.e.: properly gets subtracted from the text), just like we see
  3. // in the earlier screenshots. But, like before, I have to manually orientate this to the pipe and is currently
  4. // hard coded to be completely horizontal..
  5. //
  6.  
  7. var pipeStart = pipe.StartPoint;
  8. var pipeVector = pipeStart.GetVectorTo(pipe.EndPoint);
  9. double pipeRadius = outsideDiameter / 2.0;
  10.  
  11. var cyl = new Solid3d { RecordHistory = true };
  12. cyl.CreateFrustum(pipeLength, pipeRadius, pipeRadius, pipeRadius);
  13.  
  14. // Move it to the center of the pipe...
  15. cyl.TransformBy(Matrix3d.Displacement(pipe.CenterOfGravity - Point3d.Origin));
  16.  
  17. // And rotate it so it is horizontal... (this is bad.. why can't I use the vector or something
  18. // that was done with the text solid to move + rotate this to the proper spot?
  19.  
  20. Matrix3d matrix2 = Matrix3d.Rotation(Math.PI / 2, Vector3d.YAxis, pipe.CenterOfGravity);
  21. cyl.TransformBy(matrix2);
  22. PostToDatabase(cyl);
  23. textSolid.BooleanOperation(BooleanOperationType.BoolSubtract, cyl);
  24.  

But it doesn't work with this approach to creating the cylinder, (although it does orientate it to the pipe just like the text solid is)

Code - C#: [Select]
  1. var circle = new Circle(pipe.StartPoint, pipeVector, pipeRadius);
  2. PostToDatabase(circle);
  3.  
  4. var regs = new DBObjectCollection { circle };
  5. var regions = new DBObjectCollection();
  6. regions = Region.CreateFromCurves(regs);
  7. var reg = (Region)regions[0];
  8.  
  9. var cyl = new Solid3d
  10. {
  11.         RecordHistory = true,
  12.         ShowHistory = true
  13. };
  14. cyl.Extrude(reg, pipeLength, 0.0);
  15. PostToDatabase(cyl);
  16.  
  17. textSolid.BooleanOperation(BooleanOperationType.BoolSubtract, cyl);
  18.  
  19. erase the circle - is this needed ??
  20. if (!circle.IsWriteEnabled)
  21.         circle.UpgradeOpen();
  22. circle.Erase();
  23.  

Which results in the second screenshot in this post..

BUT.. then I looked more closely at the screenshot... maybe it did work? Why is the text appearing as solid on top of the pipe, but only as wireframe inside the pipe? If the subtraction didn't work at all, wouldn't we see the test inside the pipe be solid as well? I tried not subtracting and took a screenshot, (I manually deleted the cylinder so you can just see the pipe), and the text indeed is solid! (See 3rd screenshot).

So maybe the subtraction did work after all.. but it left the outline of the text there for some reason??