Run MESHSMOOTH through Editor.Command

Run MESHSMOOTH through Editor.Command

grahamcook
Advocate Advocate
1,218 Views
3 Replies
Message 1 of 4

Run MESHSMOOTH through Editor.Command

grahamcook
Advocate
Advocate

Hi

I am trying to create a command that converts 3DSolid entities to Mesh (not PolyFaceMesh).  (Part of a bigger command).

I couldn't find a direct way of converting using the .Net API so have looked at calling MESHSMOOTH through Editor.Command().  The code below runs with no errors but no changes are made to the solids.  The same solids convert successfully if I manually call the command on the AutoCAD command line.  If I change the code and switch the passed in command to ERASE then the process works.  So are there certain AutoCAD commands that do not support being called from Editor.Command()?

Also, if anyone knows how to convert 3DSolid to Mesh using .NET API I would be grateful to know!

 

[Autodesk.AutoCAD.Runtime.CommandMethod("VCY_CreateMesh", CommandFlags.UsePickSet)]
public void CreateMesh()
{
	Document doc = Application.DocumentManager.MdiActiveDocument;
	Database db = doc.Database;
	Editor ed = doc.Editor;

	PromptSelectionResult psr = null;

	TypedValue[] filterlist = new TypedValue[2];

	//select only 3DSOLIDs
	filterlist[0] = new TypedValue(0, "3DSOLID");

	//8 = DxfCode.LayerName
	filterlist[1] = new TypedValue(8, "Roads,Terrain");

	SelectionFilter filter = new SelectionFilter(filterlist);

	psr = ed.SelectAll(filter);

	Transaction tr = db.TransactionManager.StartTransaction();

	using (tr)
	{
		ed.Command("_.MESHSMOOTH", psr.Value, ""); // doesn't work
		//ed.Command("_.ERASE", psr.Value, ""); // does work

		// Do i need a transaction when calling ed.Command?
		tr.Commit();
	}
}

   

0 Likes
Accepted solutions (1)
1,219 Views
3 Replies
Replies (3)
Message 2 of 4

_gile
Consultant
Consultant

Hi,

You should not call EditorCommand from within a transaction.

Try like this:

[CommandMethod("VCY_CreateMesh")]
public static void CreateMesh()
{
    var ed = Application.DocumentManager.MdiActiveDocument.Editor;

    var filter = new SelectionFilter(new[] { 
        new TypedValue(0, "3DSOLID"), 
        new TypedValue(8, "Roads,Terrain") });

    var psr = ed.SelectAll(filter);

    if (psr.Status == PromptStatus.OK)
        ed.Command("_.MESHSMOOTH", psr.Value, "");
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 4

grahamcook
Advocate
Advocate

Hi

Thanks for responding.  Removing the transaction made no difference.  But it turns out if I test this on two very simple primitive solids (a box) then it works.  If the solids are non-primitive solids and I run the MESHSMOOTH manually in the command prompt I get the attached dialog prompt.  I tick the box and click Create Mesh and my solid gets converted.  Now, you would think that because I have ticked the box that any subsequent conversions will just convert without the prompt being shown but that's not the case if I call the MESHSMOOTH command from Editor.Command().
The Revit API has an option to deal with Failures or popup warnings of this nature (FailuresAccessor class) so I wonder if there is anything similar in the AutoCAD API?  Anyway, I suspect that the popup (which doesn't actually show when automating through Editor.Command()) is influencing the result here.  Popup dialog is attached.

0 Likes
Message 4 of 4

grahamcook
Advocate
Advocate
Accepted solution

Hi

 

In the end I found out how to do this by creating a SubDMesh:

 

[CommandMethod("VCY_CreateMesh")]
public static void CreateMesh()
{
    var ed = Application.DocumentManager.MdiActiveDocument.Editor;

    var filter = new SelectionFilter(new[] { 
        new TypedValue(0, "3DSOLID"), 
        new TypedValue(8, "Roads,Terrain") });

    var psr = ed.SelectAll(filter);

    if (psr.Status != PromptStatus.OK)
        return;

    Transaction tr = db.TransactionManager.StartTransaction();
    using (tr)
    {
        for (int i = 0; i < psr.Value.Count; i++)
        {
            Solid3d mySolid = 
             (Solid3d)psr.Value[i].ObjectId.GetObject(OpenMode.ForWrite);

            MeshFaceterData mfd = new MeshFaceterData();
            mfd.FaceterMeshType = 0;
            mfd.FaceterMaxEdgeLength = 0;
              
            // Create new mesh from solid (smoothing level 0)
            MeshDataCollection meshData = 
                          SubDMesh.GetObjectMesh(mySolid, mfd);
            SubDMesh myMesh = new SubDMesh();
            myMesh.SetSubDMesh(meshData.VertexArray, 
                            meshData.FaceArray, 0); // smoothing 0

            // Add mesh to database.
            myMesh.SetDatabaseDefaults();
            BlockTableRecord btr = 
                 (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, 
                          OpenMode.ForWrite);
            btr.AppendEntity(myMesh);
            tr.AddNewlyCreatedDBObject(myMesh, true);

            mySolid.Erase();
        }
                
        tr.Commit();
    }
}