SEANT 发表于 2022-7-6 21:55:47

.NET - Find COG of linear elem

Here is a prototype C# routine to create a point at the center of gravity of a selection set of lines and/or polylines (without bulges).
 
This example code is in response to the query made in this thread:
http://www.cadtutor.net/forum/showthread.php?t=48143
 
Limited testing.Use sensible precaution!
 
To run:
 
unzip lcog.zip
 
 
 
In AutoCAD:
 
Command: netload
(navigate to, and load file LCOG.dll)
 
Command: LCOG
Select linear elements:
 
 

// Written by Sean Tessier June 25 2010// Rev1 - Bug fix June 27 2010using System;using System.Collections.Generic;using Autodesk.AutoCAD.Runtime;using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.DatabaseServices;using Autodesk.AutoCAD.EditorInput;using Autodesk.AutoCAD.Geometry;namespace LinesCOG{   public class CTCommands   {       public CTCommands()       {       }              static public void LCOGinit()       {         Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;         Database db = HostApplicationServices.WorkingDatabase;         ObjectIdCollection oidColl = new ObjectIdCollection();         WeightedMidCollection wmc = new WeightedMidCollection();         PromptSelectionOptions pso = new PromptSelectionOptions();         pso.MessageForAdding = "\nSelect linear elements: ";         pso.SinglePickInSpace = true;         pso.SingleOnly = true;         Vector3d v3d = new Vector3d(0.0, 0.0, 1.0);         //Only process lines and polylines with an elevation of 0         TypedValue[] filter = { new TypedValue(-4, "")                                 };         SelectionFilter selFilter = new SelectionFilter(filter);         bool Canceled = false;         using (Transaction trans = db.TransactionManager.StartTransaction())         {               do               {                   PromptSelectionResult result = ed.GetSelection(pso, selFilter);                   if (result.Status == PromptStatus.OK)                   {                     ObjectId[] oids = result.Value.GetObjectIds();                           foreach (ObjectId oid in oids)                           {                               if (!oidColl.Contains(oid))                               {                                 oidColl.Add(oid);                                 Line ln = trans.GetObject(oid, OpenMode.ForRead) as Line;                                 if (ln != null)                                 {                                       Point3d stpt = ln.StartPoint;                                       Point3d ndpt = ln.EndPoint;                                       if (stpt.Z == 0.0 && ndpt.Z == 0.0)//only process lines on the WCS XY                                       {                                           ln.Highlight();                                           WeightedMid wm = new WeightedMid(new Point2d(ln.StartPoint.X, ln.StartPoint.Y),                                             new Point2d(ln.EndPoint.X, ln.EndPoint.Y));                                           wmc.Add(wm);                                       }                                 }                                 else                                 {                                       Polyline pln = trans.GetObject(oid, OpenMode.ForRead) as Polyline;                                       if (pln != null && !pln.HasBulges)//exclude polylines with bulges                                       {                                           for (int i = 0; i < pln.NumberOfVertices - 1; i++)                                           {                                             WeightedMid wm = new WeightedMid(pln.GetPoint2dAt(i), pln.GetPoint2dAt(i + 1));                                             wmc.Add(wm);                                           }                                           pln.Highlight();                                           if (!oidColl.Contains(oid)) oidColl.Add(oid);                                       }                                 }                               }                           }                           ed.WriteMessage("\nPocessing " + oidColl.Count.ToString() + " linear elements");                   }                   else Canceled = true;               } while (!Canceled);               if (oidColl.Count == 0) return;               wmc.ProccessMids();               if (wmc.IsValid)               {                   try                   {                     DBPoint COGpt = new DBPoint(wmc.COG);                     BlockTableRecord btr = (BlockTableRecord)(trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite));                     btr.AppendEntity(COGpt);                     trans.AddNewlyCreatedDBObject(COGpt, true);                   }                   catch                   {                     ed.WriteMessage("\nExecution Error:Operation cancelled!");                   }                   finally                   {                     foreach (ObjectId oid in oidColl)//remove highlighting                     {                           Entity ent = trans.GetObject(oid, OpenMode.ForRead) as Entity;                           ent.Unhighlight();                     }                   }               }               else ed.WriteMessage("\nOperation aborted!");               trans.Commit();         }       }   }   struct WeightedMid //Process individual lines   {       //fields       public double X;       public double Y;       public double MomentX;       public double MomentY;       public double length;       //Constructor       public WeightedMid(Point2d StartPoint, Point2d EndPoint)       {         X = (StartPoint.X + EndPoint.X) / 2.0;         Y = (StartPoint.Y + EndPoint.Y) / 2.0;         length = StartPoint.GetDistanceTo(EndPoint);         MomentX = length * X;         MomentY = length * Y;       }   }   class WeightedMidCollection : List //Process lines as a collection   {       //Fields       private double m_totLength;       private Point3d m_cog;       private double m_combinedXMoments;       private double m_combinedYMoments;       private bool m_isValid = false;       //Constructor       public WeightedMidCollection()       {       }       //Properties       public Point3d COG       {         get { return m_cog; }       }       public bool IsValid       {         get { return m_isValid; }       }       //Methods       public void ProccessMids()       {         foreach (WeightedMid wm in this)         {               m_totLength += wm.length;               m_combinedXMoments += wm.MomentX;               m_combinedYMoments += wm.MomentY;         }         try         {               m_cog = new Point3d(m_combinedXMoments / m_totLength, m_combinedYMoments / m_totLength, 0.0);               m_isValid = true;         }         catch         {               m_isValid = false;         }       }   }}
LCOG_rev2.zip

Pete_IC 发表于 2022-7-6 22:00:52

SEANT, i get a fatal error when I try and use LCOG, got any ideas why?

SEANT 发表于 2022-7-6 22:03:46

That’s not good.AutoCAD 2009 is the platform with which I debugged and compiled.Conceivably, though, it should work with anything 2007+
 
Are you using the 64bit version?Is there any additional information you can give me?

Pete_IC 发表于 2022-7-6 22:05:27

As far as i know its just normal full version 2009, the only difference is its a floating version so the license is on our server as we also run 2006LT.
 
Later on today I will see if it works on a different computer.

SEANT 发表于 2022-7-6 22:09:16

I’m not sure what the ramifications are with regard to floating licenses.I’ll look into that asap.
 
The LCOG.dll should be run from a local drive (i.e., not from a server).Is that the case?

Pete_IC 发表于 2022-7-6 22:14:08

that could be the problem I will more it to a local drive and give it a go

Pete_IC 发表于 2022-7-6 22:15:03

that was the problem, needed to be on a local drive

SEANT 发表于 2022-7-6 22:20:20

Cool.I've got to remember to make that known up front.
 
Thanks.

Pete_IC 发表于 2022-7-6 22:24:08

Now its working I have noticed if i select the polylines using LCOG I get a point, then if I do it again I get another point, but its in a slightly different location.

SEANT 发表于 2022-7-6 22:26:34

Could you put that geometry in a separate file and upload it here?
页: [1] 2
查看完整版本: .NET - Find COG of linear elem