Testing the .NET Solid3d.CreateSculptedSolid() method via the implemented SURFSCULPTX command !

I read in the release notes of V22 that the experimental sculpted solid API was introduced in V22 and experimental implementations of the C++ AcDb3dSolid::createSculptedSolid() and .NET Solid3d.CreateSculptedSolid() functions are now available for preliminary testing.
So I gave it a try and implemented the SURFSCULPTX command in C#, in order to test the functionality.

I have also used the same code to test the above command in ACAD 2022 and here are the results:
Green Solids in cases (1) (7) and (8) were created but NOT the Red solids in cases (2) (3) (4) (5) (6) (7) (8).
The red “sculpted” solids were created in ACAD 2022 using exactly the same code for the SURFSCULPTX command.

(1) 4 planar extruded surfaces and 2 planar surfaces
(2) 1 conic surface and 2 planar surfaces
(3) 1 swept surface, 1 cylindrical surface, 1 planar surface
(4) 1 lofted surface, 1 cylindrical surface, 1 planar surface
(5) 2 planar surfaces, 4 arc-extruded surfaces OR 1 spline extruded surface
(6) 2 cylindrical surfaces, 1 planar surface
(7) 2 planar surfaces(1 inclined), 1 spherical surface, 1 inclined cylindrical surface
(8) 2 planar surfaces, 2 spherical surfaces, 1 cylindrical surface

Comparing cases (7) and (8), we see that a sculpted solid is NOT created if the cylindrical surface is inclined to the planar surfaces (blue) !!!




A very interesting aspect of the method Solid3d.CreateSculptedSolid() is that it can union surfaces and solids…!
as shown below :




The DELOBJ system variable doesn’t seem to play any role, whether enclosing surfaces and solids are retained or not?
I have also noticed that selected enclosing surfaces are consumed in a rather “peculiar” way , somehow they disappear from the display, although they are still there and selectable…???
If you select them by SELECT> ALL , you get them into a selection set but they don’t display….????
This is the reason, as you can see in the attached source code, why I use clones of the selected surfaces and solids in the Solid3d.CreateSculptedSolid() method, to be deleted and disposed after the operation!

// open the 1st entity (surface or solid)...
SurfSolEnt = tr.GetObject(idarray[i], OpenMode.ForRead) as Entity;
// add it to an entity list...
entList.Add((Entity)SurfSolEnt.Clone());

That’s all for now…
You find in the attachment the plugin for the command SurfSculptX.dll, the test DWG and the source code.
NETLOAD the SurfSculptX.dll and call the command SURFSCULPTX
I greatly appreciate any feedback from using the command, changing and adapting the source code, particularly by programmers and developers having written similar code in C++ being able to create the correct solids in all described cases (1)-(8) failing to create them.
Enjoy

Comments

  • Owen Wengerd
    edited February 2022
    Very nice work, and useful feedback as we continue to improve this functionality!

    I took a quick look at your source code. What is the reason for making clones of the selected source entities? I expect this is why you noticed strange behavior. Shallow clones can still be sharing data with the source entity, so it's not surprising that the source entity gets confused. If you really need clones, it would be better to DeepClone() the source entities or WblockClone() them to a temporary database. Also, I don't think it's possible to erase NDBR clones (but they do need to be deterministically disposed).
  • Hi Owen,
    Thanks for your positive comments and for checking the source !
    Well, the strange behavior of the consumed entities(surfaces) occurs without using clones and that's why i used them. The strange behavior is not the result of using clones !
    In order to reproduce the problem, just use the attached dwg and replace in code the line
    entList.Add((Entity)SurfSolEnt.Clone()); with
    entList.Add(SurfSolEnt);

    Now follow the steps:
    Call SURFSCULPTX, select all surfaces and produce the red solid.
    Select ALL entities...
    You have 1 solid entity, 2 plane surfaces and 4 extruded planar surfaces.



    Call the REGEN command and you get ONLY the solid displayed on the screen, the surfaces disappear although they were displayed and could be selected after the SURFSCULPTX operation !

    Now call the SELECT > ALL command and 7 entities are selected 1 solid and 6 surfaces but you see only the solid on the screen. This is really peculiar behavior.....
    So i decided to use clones to workaround this behavior, and retain the surfaces for future operations without problems so far...! The DELOBJ system variable doesn’t seem to play any role as already mentioned.
    I think one should be able to choose, whether surfaces consumed by the operation are deleted or not....



  • i forgot the dwg to test....
  • Owen Wengerd
    edited February 2022
    I tested the (clone-less) code with SurfSculptXTest6.dwg on a current internal build of V22 and could not reproduce the phantom surface problem. In case I unintentionally changed something that affects it, here is my modified test code (using our standard namespace aliases):

    [_AcTrx.CommandMethod("SURFSCULPTX", _AcTrx.CommandFlags.UsePickSet)] public void createSculpted() { // get the usuals _AcAp.Document doc = _AcAp.Application.DocumentManager.MdiActiveDocument; _AcDb.Database db = doc.Database; _AcEd.Editor ed = doc.Editor; _AcDb.Transaction tr = db.TransactionManager.StartTransaction(); // select filtered enclosing solids and surfaces.... _AcEd.PromptSelectionOptions opts = new _AcEd.PromptSelectionOptions(); opts.MessageForAdding = "Select enclosing Surfaces and Solids "; _AcDb.TypedValue[] selFilter = new _AcDb.TypedValue[10] { new _AcDb.TypedValue((int)_AcDb.DxfCode.Operator, "<OR"), new _AcDb.TypedValue(0 , "SURFACE"), new _AcDb.TypedValue(0 , "SWEPTSURFACE"), new _AcDb.TypedValue(0 , "LOFTEDSURFACE"), new _AcDb.TypedValue(0 , "PLANESURFACE"), new _AcDb.TypedValue(0 , "REVOLVEDSURFACE"), new _AcDb.TypedValue(0 , "EXTRUDEDSURFACE"), new _AcDb.TypedValue(0 , "NURBSURFACE"), //new _AcDb.TypedValue(0 , "MESH"), new _AcDb.TypedValue(0 , "3DSOLID"), new _AcDb.TypedValue((int)_AcDb.DxfCode.Operator, "OR>") }; _AcEd.PromptSelectionResult res = ed.GetSelection(opts, new _AcEd.SelectionFilter(selFilter)); // if selection ok if (res.Status == _AcEd.PromptStatus.OK) { _AcEd.SelectionSet ss = res.Value; _AcDb.ObjectId[] idarray = ss.GetObjectIds(); _AcDb.Solid3d pSolid = new _AcDb.Solid3d(); _AcDb.Entity SurfSolEnt; List<_AcDb.Entity> entList = new List<_AcDb.Entity>(); // this parameter according to BRX documentation above is not currently used ! _AcGe.IntegerCollection limits = new _AcGe.IntegerCollection(idarray.Length); _AcDb.BlockTable bt = (_AcDb.BlockTable)tr.GetObject(db.BlockTableId, _AcDb.OpenMode.ForRead, false); _AcDb.BlockTableRecord ms = (_AcDb.BlockTableRecord)tr.GetObject(bt[_AcDb.BlockTableRecord.ModelSpace], _AcDb.OpenMode.ForWrite, false); using (tr) { for (int i = 0; i < idarray.Length; i++) { // open the 1st entity (surface or solid)... SurfSolEnt = tr.GetObject(idarray[i], _AcDb.OpenMode.ForRead) as _AcDb.Entity; // add it to an entity list... entList.Add(SurfSolEnt); } // create sculpted solids pSolid.CreateSculptedSolid(entList.ToArray(), limits); pSolid.SetDatabaseDefaults(db); ms.AppendEntity(pSolid); tr.AddNewlyCreatedDBObject(pSolid, true); //set the current color pSolid.Color = db.Cecolor; tr.Commit(); } } }
  • With the code is everything OK!
    I tested the command on 2 different computers running Win 10, Win 11 installing BricsCAD-V22.1.07-1 and
    BricsCAD-V22.1.06-1 but the problem remains. After creating the solid i run the lisp (entget(car(entsel))) in order to create the entity list by selecting one of the surfaces being still on screen and selectable....
    I get nil ! no entity list meaning that the enclosing surface are internally consumed and disposed, although they are still displayed and selectable !
    It has rather to do with the Bricscad build i thing, you have an internal better one...!
  • As i assumed there was a bug with BricsCAD-V22.1.07-1.
    The beta V22.2.01-1 solves the problem of phantom or "ghost" surfaces, they are displayed correctly and are not deleted or disposed after the surfsculpt operation...! That's why you could not reproduce the problem.
    The problem of not creating the red solids in the cases displayed above remains though and is not yet solved by the beta version.
  • I'm glad to hear that the phantom surfaces problem is resolved. Note that beta builds are confidential, not to be discussed publicly.
  • I just wanted to give an update on the .NET Solid3d.CreateSculptedSolid() function as tested in V23 and V24.
    The cases where the enclosed space is not recognized and no solid is created, seem not to be associated with the complexity of the enclosing surfaces !
    The following 3 cases where tested using a NURBS surface (yellow), a cylindrical surface (blue), a lofted surface (green), planar surfaces(cyan) and spherical surfaces (yellow).






    in cases 1 and 3 ALL enclosed solids are created (red) depending on which surfaces are selected....
    in case 2, strange enough although the surfaces and consequently the enclosed spaces are simpler, no solids are created.
    A workaround is to imprint the cylindrical surface on the 2 spherical ones !
    The solid is then created.....



    You find attached the DWG and the assembly to test, until a full blown native command is available.
    NETLOAD the assembly and use the SURFSCULPTX command.