I am working on a tool designed for 3D operations with solid, where one from possible inputs can be old solid (element type 19).
I am aware of a fact that not ISolidKernelEntity (which I guess is also type 19) has limited support, but I was not able to implement any working code that would allow me to access the solid geometry.
The tools is "read only / query tool", so IsModifyOriginal returns true. I am not sure what is a right value returned from OnPreElementModify.
I am able to select the solid and its face(s), but I failed to do anything in OnElementModify:
public override StatusInt OnElementModify(Element element)
SubEntity subEntities = new SubEntity;
// Ok, I receive accepted faces
for (int i = 0; i < subEntities.Length; i++)
SubEntity face = subEntities[i];
IntPtr geom = default(IntPtr);
BentleyStatus getGeometryStatus = this.GetSubEntityGeometry(geom, face);
// getGeometryStatus is SUCCESS, but the pointer is always zero ... no data
BentleyStatus getFaceVerticesStatus = SolidUtil.GetFaceVertices(out vertices, face);
// getFaceVerticesStatus is always ERROR
// Element is not modifed
// From C++ documentation: ERROR to reject change or if change completely handled by tool.
I also tried to overwrite
protected override BentleyStatus OnProcessSolidPrimitive(ref SolidPrimitive geomPtr, DisplayPath path)
but the results are always the same regardless Error or Success is returned. It seems the method is never called, I was not able to reach a break point in Debug or to print a message from the method :-(
I would like to know whether I do anything wrong (e.g. to override some other method?) or there is a bug in the code (maybe two bugs? ... OnProcessSolidPrimitve not called and GetSubEntityGeometry returns success but not pointer?).
Ultimately, I need to obtain:
Jan Šlegr said:The tools is "read only / query tool", so IsModifyOriginal returns true
Shouldn't that return false?
Jan Šlegr said:I am not sure what is a right value returned from OnPreElementModify
Here are some comments from Brien Bastings...
Just wanted to add a couple things that probably aren't obvious.
DgnElementSetTool establishes the locate criteria in _SetLocateCriteria (which is called from _BeginPickElements for pick and _BuildAgenda for fences and selection sets). This is the place to add any tool specific locate criteria as opposed to _OnPostInstall.
Returning false from _IsModifyOriginal allows locked/reference elements to be selected as it puts DgnElementSetTool into copy mode. For a query only tool this can have the undesirable side-effect of cloning styles, etc. from the source to the destination.
To avoid this, a query tool should override _OnPreElementModify. If you return SUCCESS without calling super, _OnElementModify will still be called if that's where you want to have your logic to extract information from the selected elements.
Regards, Jon Summers LA Solutions
Jon Summers said:Shouldn't that return false?
Yes, of course, it's a typing error. It's false in test code and in fact it doesn't matter and the class behaves the sam in both cases.
Jon Summers said:Here are some comments from
I am aware of this discussion. After some thinking I assume this setting is not important for specifically this discussion.
Labyrinth Technology | dev.notes() | cad.point
Any idea or insight, maybe Brien Bastings or Paul Connelly?
At this point of development I would like to know whether it's bug in NET API (which probably would mean to use C++/CLI as a workaround to use the tool available functionality) or I just missunderstand how the tool API works ;-)
The non-brep types lack any sort of connectivity information, so what you can do with them is very limited. You can pick a face, edge, or vertex and get it's geometry, but that's about it, you can't ask an edge for the surrounding faces, a vertex for the surrounding edges, etc. you only get this information when you have brep topology.
The SolidUtil methods are for working with breps (ISolidKernelEntity), so it's not expected for them to support a non-brep ISubEntity. Unlike a brep sub-entity, the non-brep sub-entities are not valid after the LocateSubEntityTool exits as it's the tool that holds the connection to the original surface/solid to provide even the minimal topology support that it does.
//! Return true if the supplied subEntity represents an face, edge, or vertex of an ISolidKernelEntity and is valid for the solid modelling api.DGNVIEW_EXPORT bool LocateSubEntityTool::IsSolidKernelSubEntity (ISubEntityCR subEntity);
That said, what you are looking to do is possible (using C++ at least) without trying to promote everything to brep:
Jan Šlegr said:Ultimately, I need to obtain:
geometry (and vertices), when a user selects face
curve (and end points), when a user selects edge
point, when a user selects vertex
There's the tool method you discovered to get the geometry from a sub-entity, and the C++ version should certainly return a valid IGeometryPtr.
//! Get an IGeometryPtr that holds the geometric representation for the supplied sub-entity.DGNVIEW_EXPORT BentleyStatus LocateSubEntityTool::GetSubEntityGeometry (IGeometryPtr& geom, ISubEntityCR subEntity);
For a planar face, the IGeometry returned will be a region CurveVector and it will be easy enough to collect the vertices. A non-planar face can be returned as a surface or revolution or ruled sweep...if you need to get vertices from these, you'll have to get the edges curves and extract the vertices from those.
For an edge, the IGeometry will be an open CurveVector containing a single CurvePrimitive that you can ask for the start/end points.
For a vertex, I believe the IGeometry will be a "none" boundary type CurveVector containing a single point string CurvePrimitve.
* For an edge or vertex you could also use LocateSubEntityTool::TryGetAsCurveLocationDetail instead to get both the CurvePrimitive and pick information...
Jan Šlegr said:I would like to know whether I do anything wrong (e.g. to override some other method?) or there is a bug in the code (maybe two bugs? ... OnProcessSolidPrimitve not called and GetSubEntityGeometry returns success but not pointer?).
Yes, these do sound like bugs, I can only vouch for the C++ api and not the wrappers...
Answer Verified By: Jan Šlegr
thanks for your explanation. I plan to write similar C++ code as I did in C# and will compare where it behaves differently, because what you wrote is what I exepcted in C#.
When C++ will work as expected (and I am quite it will :-), I will probably make native implementation of the functionality, available to the rest of application (has to be in managed from reasons I do not control) using C++/CLI.