Bryco 发表于 2011-9-20 14:36:07

X剪辑和块插入点

Kean在这里有一个很好的xclip工作示例http://through-the-interface.typepad.com/through_the_interface/2010/11/adding-a-2d-spatial-filter-to-perform-a-simple-xclip-on-an-external-reference-in-autocad-using-net.html
然而,这对我没有帮助,因为我正在尝试更新现有的剪辑信息
下面是一个工作函数,用于更改块的插入,在获得xclipped blockref之前,该函数工作正常
如果在XCLIPFRAME设置为2或1且图形中有剪裁的blockref的情况下运行以下代码,您将看到剪辑移动到LALALand中的某个位置
代码只是复制现有剪辑信息,然后以某种愚蠢的形式将其恢复。有人知道它在做什么吗
      
      public static void NewInsertionPoint()
      {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            //Get the blockreference
            PromptEntityOptions peo = new PromptEntityOptions("Pick a blockreference to change the insertion point:");
            peo.SetRejectMessage("Must be a blockreference:");
            peo.AddAllowedClass (typeof(BlockReference),true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;
            //New insertion point
            PromptPointResult ppo=ed.GetPoint("Pick the new insertion point:");
            if (ppo.Status != PromptStatus.OK) return;
            Matrix3d ucs=ed.CurrentUserCoordinateSystem;
            Point3d insPt = ppo.Value.TransformBy(ucs),newPt;
            bool hasAtts=false;
            
            using(Transaction tr = db.TransactionManager.StartTransaction())      
            {
                BlockReference br = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;
                ObjectId blockId=br.BlockTableRecord;
                BlockTableRecord btr = tr.GetObject(blockId, OpenMode.ForWrite) as BlockTableRecord;
                Plane plane=new Plane(ucs.CoordinateSystem3d.Origin,ucs.CoordinateSystem3d.Zaxis);
                //Transform inspt back to the blockdef
                Matrix3d blockmatrix = br.BlockTransform;
                insPt= insPt.TransformBy(blockmatrix.Inverse());
                //Util.AddEnt.Point(insPt, 2);
                Vector3d v=btr.Origin-insPt;
                Matrix3d move=Matrix3d.Displacement(v);
                Matrix2d disp = Matrix2d.Displacement(insPt.Convert2d(plane)-btr.Origin.Convert2d(plane));
      
                //Move the ents in the block
                foreach (ObjectId id in btr)
                {
                  Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
                  ent.TransformBy(move);
                  ent.DowngradeOpen();
                  if(ent.GetType()==typeof(AttributeDefinition))
                        hasAtts=true;
                }
                ObjectIdCollection ids = btr.GetBlockReferenceIds(false, true);
                //Move the BlockReferences
                foreach (ObjectId brefId in ids)
                {
                  bool btrans = false;
                  BlockReference b = tr.GetObject(brefId, OpenMode.ForWrite) as BlockReference;
                  if (b.BlockTableRecord == blockId)
                  {
                        newPt = insPt.TransformBy(b.BlockTransform);
                        b.TransformBy(Matrix3d.Displacement(newPt - b.Position));
                        btrans = true;
                  }
                  else
                  {
                        BlockTableRecord nestedBref = tr.GetObject(b.BlockTableRecord, OpenMode.ForWrite) as BlockTableRecord;
                        foreach (ObjectId id in nestedBref)
                        {
                            if (id == brefId)
                            {
                              newPt = insPt.TransformBy(b.BlockTransform);
                              b.TransformBy(Matrix3d.Displacement(newPt - b.Position));
                              btrans = true;
                              break;
                            }
                        }
                  }
                  if (btrans)
                  {
                        ObjectId id = b.ExtensionDictionary;
                        if (id == ObjectId.Null) continue;
                        DBDictionary dic = tr.GetObject(id, OpenMode.ForWrite) as DBDictionary;
                        const string spatialName = "SPATIAL";
                        DBDictionary FilterDic = tr.GetObject(dic.GetAt("ACAD_FILTER"), OpenMode.ForWrite) as DBDictionary;
                        if (!FilterDic.Contains(spatialName)) continue;
                        SpatialFilter sf = tr.GetObject(FilterDic.GetAt(spatialName), OpenMode.ForWrite) as SpatialFilter;
                        SpatialFilterDefinition def = sf.Definition;
                        Point2dCollection pts = new Point2dCollection();
                        foreach (Point2d pt in def.GetPoints())
                        {
                           //pts.Add(pt.TransformBy(disp));
                            pts.Add(pt);
                        }
                        SpatialFilterDefinition NewDef = new SpatialFilterDefinition
                            (def.GetPoints(), def.Normal, def.Elevation, def.FrontClip, def.BackClip, def.Enabled);
                        //SpatialFilterDefinition NewDef = new SpatialFilterDefinition
                        //    (pts, def.Normal, def.Elevation, def.FrontClip, def.BackClip, def.Enabled);
                        SpatialFilter NewSf = new SpatialFilter();
                        NewSf.Definition = NewDef;
                        FilterDic.Remove(spatialName);
                        FilterDic.SetAt(spatialName, NewSf);
                        tr.AddNewlyCreatedDBObject(NewSf, true);
                  }
                }
                if (hasAtts)
                  Blocks.blocks.UpdateAtts(blockId, db);
            tr.Commit();      
            }
            
      } // end NewInsertionPoint
**** Hidden Message *****

Bryco 发表于 2011-9-20 23:23:40

再近一点,您必须减去块引用位置。
foreach (Point2d pt in def.GetPoints())
{
pts.地址(pt);
}

为 Vector3d v3 = br。Position.GetAsVector();
foreach (Point2d pt in def.GetPoints())
{
Point3d p = new Point3d(pt.X,pt.是的,防守海拔);
p = p -v3;
分。Add(p.Convert2d(plane));
}
但是,如果您复制剪辑的块引用,则会导致所有剪辑和块引用都转到剪辑的 forst 实例

Kerry 发表于 2011-9-21 06:11:40

追踪布莱斯看起来是个大问题。
...希望我有时间玩
可能值得尝试调整斯蒂芬普雷斯顿或基恩的兴趣...

Bryco 发表于 2011-9-21 07:34:49

感谢您的回复克里,您的建议听起来不错。
我把它分成了2个函数
      
      public static void NewInsertionPoint()
      {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            PromptEntityOptions peo = new PromptEntityOptions("Pick a blockreference to change the insertion point:");
            peo.SetRejectMessage("Must be a blockreference:");
            peo.AddAllowedClass (typeof(BlockReference),true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;
            PromptPointResult ppo=ed.GetPoint("Pick the new insertion point:");
            if (ppo.Status != PromptStatus.OK) return;
            Matrix3d ucs=ed.CurrentUserCoordinateSystem;
            Point3d insPt = ppo.Value.TransformBy(ucs),newPt;
         
            using(Transaction tr = db.TransactionManager.StartTransaction())      
            {
                BlockReference br = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;
                ObjectId blockId=br.BlockTableRecord;
                BlockTableRecord btr = tr.GetObject(blockId, OpenMode.ForWrite) as BlockTableRecord;
                Matrix3d blockmatrix = br.BlockTransform;
                insPt= insPt.TransformBy(blockmatrix.Inverse());
                Vector3d v=btr.Origin-insPt;
                Matrix3d move=Matrix3d.Displacement(v);
                foreach (ObjectId id in btr)
                {
                  Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
                  ent.TransformBy(move);
                  ent.DowngradeOpen();
                }
                ObjectIdCollection ids = btr.GetBlockReferenceIds(false, true);
                foreach (ObjectId brefId in ids)
                {
                  BlockReference b = tr.GetObject(brefId, OpenMode.ForWrite) as BlockReference;
                  newPt = insPt.TransformBy(b.BlockTransform);
                  if (b.BlockTableRecord == blockId)
                  {   
                        b.TransformBy(Matrix3d.Displacement(newPt - b.Position));
                  }
                  else
                  {
                        BlockTableRecord nestedBref = tr.GetObject(b.BlockTableRecord, OpenMode.ForWrite) as BlockTableRecord;
                        foreach (ObjectId id in nestedBref)
                        {
                            if (id == brefId)
                            {
                              b.TransformBy(Matrix3d.Displacement(newPt - b.Position));
                              break;
                            }
                        }
                  }
                  UpdateClip(db, b, v);
                }
            tr.Commit();      
            }
            ed.Regen();
      } // end NewInsertionPoint
      public static void UpdateClip(Database db,BlockReference br,Vector3d v)
      {
            const string spatialName = "SPATIAL";
            ObjectId ExId = br.ExtensionDictionary;
            if (ExId == ObjectId.Null) return;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary dic = tr.GetObject(ExId, OpenMode.ForWrite) as DBDictionary;
                if (!dic.Contains("ACAD_FILTER")) return;
                DBDictionary clipDic = tr.GetObject(dic.GetAt("ACAD_FILTER"), OpenMode.ForWrite) as DBDictionary;
                if (!clipDic.Contains(spatialName)) return;
                SpatialFilter sf = tr.GetObject(clipDic.GetAt(spatialName), OpenMode.ForWrite) as SpatialFilter;
                SpatialFilterDefinition def = sf.Definition;
                Plane plane=new Plane(new Point3d(0,0,def.Elevation),def.Normal);
                Matrix3d m = br.BlockTransform;
                Matrix3d disp=Matrix3d.Displacement(v.Negate());
                Point2dCollection pts = new Point2dCollection();
                foreach (Point2d pt in def.GetPoints())
                {         
                  Point3d p = new Point3d(pt.X, pt.Y,def.Elevation);
                  p = p.TransformBy(m.Inverse());
                  pts.Add(p.Convert2d(plane));
                }
                SpatialFilterDefinition def2=new SpatialFilterDefinition(
                  pts,def.Normal,def.Elevation,def.FrontClip,def.BackClip,def.Enabled);
               
                clipDic.Remove(spatialName);
                SpatialFilter sf2 = new SpatialFilter();
                sf2.Definition = def2;
                SpatialFilterVolume sfv=sf.GetVolume();
                clipDic.SetAt(spatialName, sf2);
                tr.AddNewlyCreatedDBObject(sf2,true);
               
                tr.Commit();
            }
      } // end UpdateClip
,这是大多数情况下第一次工作,但第二次它抛出一个摆动器。此外,如果你剪辑一个块引用,然后旋转它,它会出错,所以复合矩阵需要退后一步。一开始,我认为我必须相对于新的插入点移动剪辑,但我没有。

Bryco 发表于 2014-10-28 16:48:36

我在2015年用VS2012 express和crash再次尝试了这一点,事实上,运行Kean的代码也会崩溃。我希望有人能在2015年尝试基恩代码

Bryco 发表于 2015-3-17 17:24:38

http://through-the-interface.typepad.com/through_the_interface/2010/11/adding-a-2d-spatial-filter-to-perform-a-simple-xclip-on-an-external-reference-in-autocad-using-net.html
以防万一其他人对剪辑感兴趣。这崩溃为我 ACAD 2015 机械使用香草. 基恩说他在2015年尝试过,它没有崩溃,所以我有点迷茫。希望别人可以试一试

Bryco 发表于 2015-3-18 04:09:58

我可以让 Kean 和此示例 http://adndevblog.typepad.com/autocad/2013/01/spatial-filter-xclip-command-command-in-c.html 将剪辑添加到外部参照。
但是,如果它不会反转,并且如果使用握把编辑剪辑,它就会崩溃。

Bryco 发表于 2015-3-18 13:32:29

谢谢你的努力,杰夫,我想我会放弃的。如果我单步执行代码,它不会崩溃,但我也不能编辑剪辑,有时我可以删除剪辑,但不能重新剪辑。
较新的代码看起来需要用较新的cad版本更新,所以我可能也会跳过这一步。
可惜,否则更改插入点代码真的很方便。

Bryco 发表于 2016-4-29 19:44:11

这似乎工作正常。
它不允许剪辑与blockref在不同的平面上。
在保存关闭并重新打开之前,不会显示剪辑夹点。

      
      public static void NewInsertionPoint()
      {
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            //Get the blockreference
            PromptEntityOptions peo = new PromptEntityOptions("\nPick a blockreference to change the insertion point:");
            peo.SetRejectMessage("Must be a blockreference:");
            peo.AddAllowedClass (typeof(BlockReference),true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;
            //New insertion point
            PromptPointResult ppo=ed.GetPoint("\nPick the new insertion point:");
            if (ppo.Status != PromptStatus.OK) return;
            Matrix3d ucs=ed.CurrentUserCoordinateSystem;
            Point3d insPt = ppo.Value.TransformBy(ucs),newPt=Point3d.Origin;
            bool hasAtts=false;
            
            using(Transaction tr = db.TransactionManager.StartTransaction())      
            {
                //Get the blockref
                BlockReference br = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;
                ObjectId blockId=br.BlockTableRecord;
                //get it's blockdef
                BlockTableRecord btr = tr.GetObject(blockId, OpenMode.ForWrite) as BlockTableRecord;
   
                //Transform inspt back to the blockdef
                Matrix3d blockmatrix = br.BlockTransform;
                insPt= insPt.TransformBy(blockmatrix.Inverse());
                Matrix3d move = Matrix3d.Displacement(btr.Origin - insPt);
      
                //Move the ents in the block
                foreach (ObjectId id in btr)
                {
                  Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
                  ent.TransformBy(move);
                  if(ent.GetType()==typeof(AttributeDefinition))
                        hasAtts=true;
                }
                ObjectIdCollection ids = btr.GetBlockReferenceIds(false, true);
                //Move the BlockReferences
                Matrix3d mBref = new Matrix3d();
               
                foreach (ObjectId brefId in ids)
                {
                  bool btrans = false;
                  BlockReference b = tr.GetObject(brefId, OpenMode.ForWrite) as BlockReference;
                  Point3d bposition = b.Position;
                  if (b.BlockTableRecord == blockId)//has to unless nested
                  {
                        newPt = insPt.TransformBy(b.BlockTransform);
                        mBref=Matrix3d.Displacement(newPt - b.Position);
                        b.TransformBy(mBref);
                        btrans = true;
                  }
                  else
                  {
                        BlockTableRecord nestedBref = tr.GetObject(b.BlockTableRecord, OpenMode.ForWrite) as BlockTableRecord;
                        foreach (ObjectId id in nestedBref)
                        {
                            if (id == brefId)
                            {
                              newPt = insPt.TransformBy(b.BlockTransform);
                              b.TransformBy(mBref);
                              btrans = true;
                              break;
                            }
                        }
                  }
                  if (btrans)
                  {
                        ObjectId id = b.ExtensionDictionary;
                        if (id == ObjectId.Null) continue;
                        DBDictionary dic = tr.GetObject(id, OpenMode.ForWrite) as DBDictionary;
                        const string spatialName = "SPATIAL";
                        if (!dic.Contains("ACAD_FILTER")) continue;
                        DBDictionary FilterDic = tr.GetObject(dic.GetAt("ACAD_FILTER"), OpenMode.ForWrite) as DBDictionary;
                        if (!FilterDic.Contains(spatialName)) continue;
                        SpatialFilter sf = tr.GetObject(FilterDic.GetAt(spatialName), OpenMode.ForWrite) as SpatialFilter;
                        SpatialFilterDefinition def = sf.Definition;
                        Point2dCollection pts = new Point2dCollection();
                        Matrix3d m = sf.OriginalInverseBlockTransform;
                     // Matrix3d w= sf.ClipSpaceToWorldCoordinateSystemTransform;
                        //need this for clips on a different plane than the blockref
                  
                        CoordinateSystem3d cs = m.CoordinateSystem3d;                     
                        Plane plane = new Plane(cs.Origin, cs.Zaxis);   
                        Matrix2d disp = Matrix2d.Displacement(newPt.Convert2d(plane) - b.Position.Convert2d(plane));
                        foreach (Point2d pt in def.GetPoints())
                        {
                            Point3d l = new Point3d(plane, pt);
                            l = l.TransformBy(move);
                            l = l.TransformBy(m);
                            pts.Add(l.Convert2d(plane));
                        }
                        pts.TrimToSize();
                        SpatialFilterDefinition NewDef = new SpatialFilterDefinition
                            (pts,Vector3d.ZAxis,0, def.FrontClip, def.BackClip, true);
                        SpatialFilter NewSf = new SpatialFilter();
                        NewSf.Definition = NewDef;
                        
                        FilterDic.Remove(spatialName);//REMOVE the old filter
                        FilterDic.SetAt(spatialName, NewSf);
                        tr.AddNewlyCreatedDBObject(NewSf, true);                     
                   }
                  if (hasAtts)
                        Blocks.blocks.UpdateAtts(blockId, db);
                }
               
            tr.Commit();      
            }
            ed.Regen();
      } // end NewInsertionPoint
页: [1]
查看完整版本: X剪辑和块插入点