예제 #1
0
파일: RcSlice.cs 프로젝트: 15831944/RabCab
        public void Cmd_RcSlice()
        {
            var acCurDoc = Application.DocumentManager.MdiActiveDocument;
            var acCurDb  = acCurDoc.Database;
            var acCurEd  = acCurDoc.Editor;

            //Call user to select a face
            var userSel = acCurEd.SelectSubentity(SubentityType.Face);

            if (userSel == null)
            {
                return;
            }

            var prSelOpts = new PromptDistanceOptions("\nEnter slice distance: ")
            {
                AllowNone     = false,
                AllowZero     = false,
                AllowNegative = false,
                DefaultValue  = SettingsUser.RcSliceDepth
            };

            //Get the offset distance
            var prSelRes = acCurEd.GetDistance(prSelOpts);


            if (prSelRes.Status != PromptStatus.OK)
            {
                return;
            }

            SettingsUser.RcSliceDepth = prSelRes.Value;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (SettingsUser.RcSliceDepth == 0)
            {
                return;
            }

            try
            {
                //Open a transaction
                using (var acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    var acSol = acTrans.GetObject(userSel.Item1, OpenMode.ForWrite) as Solid3d;

                    var faceEnt = acSol.GetSubentity(userSel.Item2);

                    using (var tempSurf = faceEnt.CreateSurfaceFromFace(acCurDb, acTrans, false))
                    {
                        var sliceSurf = Surface.CreateOffsetSurface(tempSurf, -SettingsUser.RcSliceDepth) as Surface;

                        //Sleep for 100 milliseconds to bypass an error caused by appending too qickly
                        Thread.Sleep(100);

                        Solid3d sliceSol = null;

                        try
                        {
                            sliceSol = acSol?.Slice(sliceSurf, true);
                            sliceSol?.SetPropertiesFrom(acSol);
                            acCurDb.AppendEntity(sliceSol, acTrans);
                            sliceSurf?.Dispose();
                        }
                        catch (Exception)
                        {
                            try //If the slice by surface method failed, use the slice by offset method
                            {
                                //Dispose of the unused surface and solids
                                sliceSol?.Dispose();
                                sliceSurf?.Dispose();

                                //Clone the input solid
                                var           subtSol = acSol?.Clone() as Solid3d;
                                SubentityId[] subIds  = { userSel.Item2 };

                                //Offset the cloned solids face and append it to the database
                                subtSol?.OffsetFaces(subIds, -SettingsUser.RcSliceDepth);

                                acCurDb.AppendEntity(subtSol, acTrans);

                                //Subtract the offset solid from the input solid, but don't delete it
                                Debug.Assert(acSol != null, "acSol != null");
                                Debug.Assert(subtSol != null, "subtSol != null");
                                new[] { acSol.ObjectId }.SolidSubtrahend(new[] { subtSol.ObjectId }, acCurDb, acTrans,
                                                                         false);
                            }
                            catch (Exception e)
                            {
                                //If nothing worked, dispose of everything and inform the user
                                sliceSol?.Dispose();
                                sliceSurf?.Dispose();
                                faceEnt.Dispose();
                                acCurEd.WriteMessage(e.Message);

                                acTrans.Abort();
                            }
                        }
                    }

                    faceEnt.Dispose();
                    acTrans.Commit();
                }
            }
            catch (Exception e)
            {
                acCurEd.WriteMessage(e.Message);
            }
        }
예제 #2
0
        /// <summary>
        ///     TODO
        /// </summary>
        /// <param name="objIds"></param>
        /// <param name="acCurEd"></param>
        /// <param name="acCurDb"></param>
        internal static void UpdateChildren(ObjectId[] objIds, Editor acCurEd, Database acCurDb)
        {
            using (var acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                foreach (var oId in objIds)
                {
                    if (oId.IsErased)
                    {
                        continue;
                    }

                    var pSol = acTrans.GetObject(oId, OpenMode.ForRead) as Solid3d;

                    if (pSol != null)
                    {
                        var eInfo = new EntInfo(pSol, acCurDb, acTrans);

                        if (eInfo.ChildHandles.Count > 0)
                        {
                            foreach (var cHandle in eInfo.ChildHandles)
                            {
                                var objId = acCurDb.GetObjectId(false, cHandle, 0);

                                if (objId == ObjectId.Null || objId.IsErased)
                                {
                                    continue;
                                }

                                Solid3d cSol = null;

                                try
                                {
                                    cSol = acTrans.GetObject(objId, OpenMode.ForWrite) as Solid3d;
                                }
                                catch (Exception)
                                {
                                    acCurEd.WriteMessage("\nChild was erased.");
                                }

                                if (cSol == null)
                                {
                                    continue;
                                }

                                var cInfo = new EntInfo(cSol, acCurDb, acTrans);

                                var pClone = pSol.Clone() as Solid3d;
                                if (pClone == null)
                                {
                                    continue;
                                }

                                pClone.TransformBy(eInfo.LayMatrix);


                                acCurDb.AppendEntity(pClone);
                                pClone.TopLeftTo(Point3d.Origin);
                                pClone.TransformBy(cInfo.LayMatrix.Inverse());

                                pClone.TransformBy(Matrix3d.Displacement(
                                                       pClone.GeometricExtents.MinPoint.GetVectorTo(cSol.GeometricExtents.MinPoint)));

                                pClone.SwapIdWith(cSol.ObjectId, true, true);

                                cSol.Erase();
                                cSol.Dispose();
                            }
                        }
                        else
                        {
                            acCurEd.WriteMessage("\nObject has no child objects attached.");
                        }
                    }
                }

                acTrans.Commit();
            }
        }
        protected override bool WorldDrawData(WorldDraw draw)
        {
            if (!base.WorldDrawData(draw))
            {
                return(false);
            }

            short origCol = draw.SubEntityTraits.Color;

            if (
                (_resizing || _nearMode) &&
                _resizeLocation.GetAsVector().Length > 0
                )
            {
                using (var sphere = new Solid3d())
                {
                    try
                    {
                        sphere.CreateSphere(_profRad);

                        if (sphere != null)
                        {
                            sphere.TransformBy(
                                Matrix3d.Displacement(
                                    _resizeLocation - Point3d.Origin
                                    )
                                );

                            // Draw the cursor

                            draw.SubEntityTraits.Color = ColorIndex;
                            sphere.WorldDraw(draw);
                        }
                    }
                    catch (System.Exception ex)
                    {
                        _doc.Editor.WriteMessage(
                            "\nException: {0} - {1}", ex.Message, ex.InnerException
                            );

                        ClearAllButLast(_vertices, 1);
                    }
                    finally
                    {
                        draw.SubEntityTraits.Color = origCol;
                    }
                }
            }

            // If we're currently drawing...

            if (_drawing)
            {
                Solid3d sol = null;
                try
                {
                    // If we have vertices that haven't yet been drawn...

                    if (_vertices.Count > 1 //&&
                        //_vertices.Count - 1 > _lastDrawnVertex
                        )
                    {
                        // ... generate a tube

                        if (GenerateTube(_profRad, _vertices, out sol))
                        {
                            // We now need to break the pipe...

                            // If it was created, add it to our list to draw

                            _created.Add(sol);
                            sol = null;

                            // Clear all but the last vertex to draw from
                            // next time

                            ClearAllButLast(_vertices, 1);
                        }
                    }
                }
                catch
                {
                    // If the tube generation failed...

                    if (sol != null)
                    {
                        sol.Dispose();
                    }

                    // Loop, creating the most recent successful tube we can

                    bool succeeded = false;
                    int  n         = 1;

                    do
                    {
                        try
                        {
                            // Generate the previous, working tube using all
                            // but the last points (if it fails, one more is
                            // excluded per iteration, until we get a working
                            // tube)

                            GenerateTube(
                                _profRad, GetAllButLast(_vertices, n++), out sol
                                );

                            _created.Add(sol);
                            sol       = null;
                            succeeded = true;
                        }
                        catch { }
                    }while (!succeeded && n < _vertices.Count);

                    if (succeeded)
                    {
                        ClearAllButLast(_vertices, n - 1);

                        if (_vertices.Count > 1)
                        {
                            try
                            {
                                // And generate a tube for the remaining vertices

                                GenerateTube(_profRad, _vertices, out sol);
                            }
                            catch
                            {
                                succeeded = false;
                            }
                        }
                    }

                    if (!succeeded && sol != null)
                    {
                        ClearAllButLast(_vertices, 1);
                        sol.Dispose();
                        sol = null;
                    }
                }

                // Draw our solid(s)

                draw.SubEntityTraits.Color = ColorIndex;

                foreach (DBObject obj in _created)
                {
                    Entity ent = obj as Entity;
                    if (ent != null)
                    {
                        try
                        {
                            ent.WorldDraw(draw);
                        }
                        catch
                        {}
                    }
                }

                if (sol != null)
                {
                    try
                    {
                        sol.WorldDraw(draw);
                    }
                    catch
                    { }
                }

                if (_vertices.Count > 0)
                {
                    Point3d lastPt = _vertices[_vertices.Count - 1];

                    // Create a cursor sphere

                    using (Solid3d cursor = new Solid3d())
                    {
                        try
                        {
                            cursor.CreateSphere(_profRad);

                            if (cursor != null)
                            {
                                cursor.TransformBy(
                                    Matrix3d.Displacement(lastPt - Point3d.Origin)
                                    );

                                // Draw the cursor

                                draw.SubEntityTraits.Color = ColorIndex;

                                cursor.WorldDraw(draw);
                            }
                        }
                        catch { }
                    }
                }

                if (sol != null)
                {
                    sol.Dispose();
                }
            }

            draw.SubEntityTraits.Color = origCol;

            return(true);
        }
예제 #4
0
        public void Cmd_EdgeBand()
        {
            var acCurDoc = Application.DocumentManager.MdiActiveDocument;
            var acCurDb  = acCurDoc.Database;
            var acCurEd  = acCurDoc.Editor;

            //Call user to select a face
            var userSel = acCurEd.SelectSubentity(SubentityType.Face, "\nSelect a FACE to use as cutting criteria: ");

            if (userSel == null)
            {
                return;
            }
            if (userSel.Item1 == ObjectId.Null)
            {
                return;
            }
            if (userSel.Item2 == SubentityId.Null)
            {
                return;
            }

            var insetOpts = new PromptDistanceOptions("\nEnter edge banding thickness: ")
            {
                AllowNone     = false,
                AllowZero     = false,
                AllowNegative = false,
                DefaultValue  = SettingsUser.EdgeBandThickness
            };

            //Get the offset distance
            var insetRes = acCurEd.GetDistance(insetOpts);

            if (insetRes.Status != PromptStatus.OK)
            {
                return;
            }

            SettingsUser.EdgeBandThickness = insetRes.Value;


            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (SettingsUser.EdgeBandThickness <= 0)
            {
                return;
            }

            Entity  faceEnt  = null;
            Surface tempSurf = null;
            Solid3d tempSol  = null;

            try
            {
                //Open a transaction
                using (var acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    var acSol = acTrans.GetObject(userSel.Item1, OpenMode.ForWrite) as Solid3d;

                    if (acSol == null)
                    {
                        acTrans.Abort();
                        return;
                    }

                    var innerSol = acSol.Clone() as Solid3d;

                    if (innerSol == null)
                    {
                        acTrans.Abort();
                        return;
                    }

                    acSol.Layer = acCurDb.GetCLayer(acTrans);
                    acCurDb.AppendEntity(innerSol);

                    faceEnt = acSol.GetSubentity(userSel.Item2);

                    var eInfo    = new EntInfo(acSol, acCurDb, acTrans);
                    var largestM = eInfo.GetLargestMeasurement();

                    using (tempSurf = faceEnt.CreateSurfaceFromFace(acCurDb, acTrans, false))
                    {
                        var thickness = largestM + SettingsUser.EdgeBandThickness;

                        using (tempSol = tempSurf.Thicken(-(thickness * 2), true))
                        {
                            tempSol.OffsetBody(-SettingsUser.EdgeBandThickness);

                            var cutSol = tempSol.Slice(tempSurf, true);
                            cutSol.Dispose();

                            acSol.BooleanOperation(BooleanOperationType.BoolSubtract, tempSol);
                        }
                    }

                    var acBool1 = new[] { innerSol.ObjectId };
                    var acBool2 = new[] { acSol.ObjectId };

                    acBool1.SolidSubtrahend(acBool2, acCurDb, acTrans, false);

                    acTrans.Commit();
                }
            }
            catch (Exception e)
            {
                acCurEd.WriteMessage(e.Message);
            }
            finally
            {
                if (faceEnt != null)
                {
                    faceEnt.Dispose();
                }
                if (tempSurf != null)
                {
                    tempSurf.Dispose();
                }
                if (tempSol != null)
                {
                    tempSol.Dispose();
                }
            }
        }