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); } }
/// <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); }
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(); } } }