Author Topic: Mobius Strip in C#  (Read 2741 times)

0 Members and 1 Guest are viewing this topic.

Dale Bartlett

  • Mosquito
  • Posts: 17
Mobius Strip in C#
« on: February 23, 2013, 02:39:10 AM »
Further to this post: [Mobius strip in AutoCAD 2008 or 2009 by C#], does anyone have code that builds a correct single-sided strip? This seems impossible although the old post indicates otherwise. Regards, Dale

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Mobius Strip in C#
« Reply #1 on: February 23, 2013, 01:26:51 PM »
Hi,

I do not think it is possible to create a 'true' Moebius strip with AutoCAD.
But it is possible to use the artefact shown here by luke: overlapping two lofted surfaces to 'close' the strip.

Here's a F# implementation:
Code - F#: [Select]
  1. module MoebiusStrip
  2.  
  3. open System
  4. open Autodesk.AutoCAD.DatabaseServices
  5. open Autodesk.AutoCAD.Geometry
  6. open Autodesk.AutoCAD.Runtime
  7.  
  8. [<CommandMethod("Test")>]
  9. let test () =
  10.     let computePoint angle halfWidth =
  11.         new Point3d(
  12.             (100. + halfWidth * cos (angle / 2.)) * cos angle,
  13.             (100. + halfWidth * cos (angle / 2.)) * sin angle,
  14.             halfWidth * sin (angle / 2.))
  15.     let angle = Math.PI / 15.
  16.     let db = HostApplicationServices.WorkingDatabase
  17.     use tr = db.TransactionManager.StartTransaction()
  18.     let btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) :?> BlockTableRecord
  19.     let lines =
  20.         [| for i in 0 .. 30 do
  21.             let a = angle * float i
  22.             yield new Line(computePoint a 20., computePoint a -20.) :> Entity |]
  23.     let addSurf (ents: Entity[]) =
  24.         let surf = new LoftedSurface()
  25.         surf.CreateLoftedSurface(ents, null, null, new LoftOptions())
  26.         btr.AppendEntity(surf) |> ignore
  27.         tr.AddNewlyCreatedDBObject(surf, true)
  28.     addSurf lines.[0 .. 29]
  29.     addSurf lines.[1 .. 30]
  30.     lines |> Array.iter(fun l -> l.Dispose())
  31.     tr.Commit()

And a C# implementation
Code - C#: [Select]
  1. using System;
  2. using System.Linq;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.Geometry;
  5. using Autodesk.AutoCAD.Runtime;
  6.  
  7. [assembly: CommandClass(typeof(MoebiusStrip.CommandMethods))]
  8.  
  9. namespace MoebiusStrip
  10. {
  11.     public class CommandMethods
  12.     {
  13.         [CommandMethod("Test")]
  14.         public void Test()
  15.         {
  16.             double angle = Math.PI / 15.0;
  17.             Entity[] lines = new Entity[31];
  18.             for (int i = 0; i < 31; i++)
  19.             {
  20.                 double a = i * angle;
  21.                 lines[i] = new Line(ComputePoint(a, 20), ComputePoint(a, -20));
  22.             }
  23.             Database db = HostApplicationServices.WorkingDatabase;
  24.             using (Transaction tr = db.TransactionManager.StartTransaction())
  25.             {
  26.                 BlockTableRecord btr =
  27.                     (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  28.                 AddSurf(lines.Take(30).ToArray(), btr);
  29.                 AddSurf(lines.Skip(1).ToArray(), btr);
  30.                 foreach (Line l in lines)
  31.                 {
  32.                     l.Dispose();
  33.                 }
  34.                 tr.Commit();
  35.             }
  36.         }
  37.  
  38.         private void AddSurf(Entity[] ents, BlockTableRecord btr)
  39.         {
  40.             LoftedSurface surf = new LoftedSurface();
  41.             surf.CreateLoftedSurface(ents, null, null, new LoftOptions());
  42.             btr.AppendEntity(surf);
  43.             btr.Database.TransactionManager.AddNewlyCreatedDBObject(surf, true);
  44.         }
  45.  
  46.         private Point3d ComputePoint(double angle, double halfWidth)
  47.         {
  48.             return new Point3d(
  49.                 (100 + halfWidth * Math.Cos(angle / 2.0)) * Math.Cos(angle),
  50.                 (100 + halfWidth * Math.Cos(angle / 2.0)) * Math.Sin(angle),
  51.                 halfWidth * Math.Sin(angle / 2.0));
  52.         }
  53.     }
  54. }
« Last Edit: February 23, 2013, 03:17:52 PM by gile »
Speaking English as a French Frog

kaefer

  • Guest
Re: Mobius Strip in C#
« Reply #2 on: February 23, 2013, 05:17:38 PM »
I do not think it is possible to create a 'true' Moebius strip with AutoCAD.

I think that may need some reservations to be true, like "it's not possible to create a Moebius strip with the .Net API". I've modified your approach to that end, creating two half-strips, and applied the UNION command manually.

I keep my fingers crossed that the modelling error reported by the UNION command doesn't indicate anything more serious than the loss of associativity.

Code - F#: [Select]
  1.     ...
  2.     let addSurf lines =
  3.         let lsurf = new LoftedSurface(Closed = false)
  4.         lsurf.CreateLoftedSurface(
  5.             lines, null, null, new LoftOptions() )
  6.         let oid = btr.AppendEntity lsurf
  7.         tr.AddNewlyCreatedDBObject(lsurf, true)
  8.     addSurf lines.[0 .. 15]
  9.     addSurf lines.[15 .. 30]
  10.     ...

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Mobius Strip in C#
« Reply #3 on: February 23, 2013, 07:04:05 PM »
You're right kaefer.

The upper codes can be completed using SendStringtoExecute and it seems to 'close' the strip in spite of the displayed message.

Code - C#: [Select]
  1. using System;
  2. using System.Linq;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.Runtime;
  8.  
  9. [assembly: CommandClass(typeof(MoebiusStripCs.CommandMethods))]
  10.  
  11. namespace MoebiusStripCs
  12. {
  13.     public class CommandMethods
  14.     {
  15.         [CommandMethod("Test")]
  16.         public void Test()
  17.         {
  18.             Document doc = Application.DocumentManager.MdiActiveDocument;
  19.             Database db = doc.Database;
  20.             Editor ed = doc.Editor;
  21.             double angle = Math.PI / 15.0;
  22.             Line[] lines = new Line[31];
  23.             for (int i = 0; i < 31; i++)
  24.             {
  25.                 double a = i * angle;
  26.                 lines[i] = new Line(ComputePoint(a, 20), ComputePoint(a, -20));
  27.             }
  28.             using (Transaction tr = db.TransactionManager.StartTransaction())
  29.             {
  30.                 BlockTableRecord btr =
  31.                     (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  32.                 ObjectId id1 = AddSurf(lines.Take(16).ToArray(), btr);
  33.                 ObjectId id2 = AddSurf(lines.Skip(15).ToArray(), btr);
  34.                 foreach (Line l in lines)
  35.                 {
  36.                     l.Dispose();
  37.                 }
  38.                 ed.SetImpliedSelection(new ObjectId[] { id1, id2 });
  39.                 tr.Commit();
  40.                 doc.SendStringToExecute("_union _previous \n", false, false, false);
  41.             }
  42.         }
  43.  
  44.         private ObjectId AddSurf(Entity[] ents, BlockTableRecord btr)
  45.         {
  46.             LoftedSurface surf = new LoftedSurface();
  47.             surf.CreateLoftedSurface(ents, null, null, new LoftOptions());
  48.             ObjectId id = btr.AppendEntity(surf);
  49.             btr.Database.TransactionManager.AddNewlyCreatedDBObject(surf, true);
  50.             return id;
  51.         }
  52.  
  53.         private Point3d ComputePoint(double angle, double halfWidth)
  54.         {
  55.             return new Point3d(
  56.                 (100 + halfWidth * Math.Cos(angle / 2.0)) * Math.Cos(angle),
  57.                 (100 + halfWidth * Math.Cos(angle / 2.0)) * Math.Sin(angle),
  58.                 halfWidth * Math.Sin(angle / 2.0));
  59.         }
  60.     }
  61. }
  62.  
Speaking English as a French Frog

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Mobius Strip in C#
« Reply #4 on: February 23, 2013, 07:31:24 PM »
It seems to work fine with solid3d unioning

Code - F#: [Select]
  1. module MoebiusStrip
  2.  
  3. open System
  4. open Autodesk.AutoCAD.ApplicationServices
  5. open Autodesk.AutoCAD.DatabaseServices
  6. open Autodesk.AutoCAD.EditorInput
  7. open Autodesk.AutoCAD.Geometry
  8. open Autodesk.AutoCAD.Runtime
  9.  
  10. [<CommandMethod("Moebius")>]
  11. let MoebiusStrip () =
  12.     let doc = Application.DocumentManager.MdiActiveDocument
  13.     let ed = doc.Editor
  14.     let db = doc.Database
  15.  
  16.     let computePoint angle halfWidth =
  17.         new Point3d(
  18.             (100. + halfWidth * cos (angle / 2.)) * cos angle,
  19.             (100. + halfWidth * cos (angle / 2.)) * sin angle,
  20.             halfWidth * sin (angle / 2.))
  21.  
  22.     let angle = Math.PI / 15.
  23.     use tr = db.TransactionManager.StartTransaction()
  24.     let btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) :?> BlockTableRecord
  25.  
  26.     let addSolid lines =
  27.        use lsurf = new LoftedSurface()
  28.        lsurf.CreateLoftedSurface(lines, null, null, new LoftOptions())
  29.        let solid =lsurf.Thicken(2., true)
  30.        let id = btr.AppendEntity solid
  31.        tr.AddNewlyCreatedDBObject(solid, true)
  32.        solid
  33.  
  34.     let lines =
  35.         [| for i in 0 .. 30 do
  36.             let a = angle * float i
  37.             yield new Line(computePoint a 20., computePoint a -20.) :> Entity |]
  38.     let solid1 = addSolid lines.[0 .. 15]
  39.     let solid2 = addSolid lines.[15 .. 30]
  40.     lines |> Array.iter(fun l -> l.Dispose())
  41.     solid1.BooleanOperation(BooleanOperationType.BoolUnite, solid2)
  42.     tr.Commit()
Speaking English as a French Frog

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: Mobius Strip in C#
« Reply #5 on: February 25, 2013, 06:49:40 AM »
Thank you, gile and kaefer for your sharing.

I have ever use mesh to generate for such type entity

in
http://www.theswamp.org/index.php?topic=41630.msg467330#msg467330

but not solid.
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)