Hi All,
I have a Bspline Surface with a set of boundaries whose clockwise sense is set to "Solid". Is it possible through MDL API to get the equivalent set of boundaries on the same Bspline Surface whose clockwise sense is "Hole"?
Thanks & Regards,
kaab
It's not clear what you are asking. What is your definition of 'solid' and 'hole'?
Regards, Jon Summers LA Solutions
Hi Jon,
To be more clear, I'll put my question this way. I have a BSpline Surface with 4 boundaries. If I see the Element Information for the Bspline Surface in MicroStation, under Geometry section, inside Trim Loop node, I see a field with name "Clockwise Sense" and its value is set to "Hole"
Now, if I change the value to "Solid", MicroStation changes the display of the Bspline Surface such that the parts which were earlier holes now become filled and the ones which were earlier filled, now become holes. But, I've seen that the Trim loops shown in the Element Information dialog still remain the same.
Now, I want to extract the boundaries of the holes shown for this new surface, using MDL API. Which API can I use for this purpose?
Thank you for your suggestion, Yongan.
Regards,
I have coded to test my suggestion and can get a re-constructed simple SmartSurface as below:
The code is simpler than I expected:
MSElementDescrP edP = NULL; KIBODY *pBody = NULL; if(SUCCESS != mdlAssoc_getElementDescr(&edP, NULL, 199, ACTIVEMODEL, FALSE)) return -1; mdlKISolid_elementToBody (&pBody, edP, ACTIVEMODEL); mdlElmdscr_freeAll (&edP); edP = NULL; if (SUCCESS == mdlKISolid_bodyToElement (&edP, pBody, TRUE, -1, NULL, ACTIVEMODEL)) { mdlKISolid_freeBody (pBody); mdlElmdscr_add (edP); mdlElmdscr_freeAll (&edP); }199 is the ElmentID of the Bspline surface which Trim Loop's Closewise Sense = Solid. The created SmartSurface has two arcs and two lines as its boundary.
MSElementDescrP edP = NULL; KIBODY *pBody = NULL; if(SUCCESS != mdlAssoc_getElementDescr(&edP, NULL, 199, ACTIVEMODEL, FALSE)) return -1; mdlKISolid_elementToBody (&pBody, edP, ACTIVEMODEL); mdlElmdscr_freeAll (&edP); edP = NULL; if (SUCCESS == mdlKISolid_bodyToElement (&edP, pBody, TRUE, -1, NULL, ACTIVEMODEL)) { mdlKISolid_freeBody (pBody); mdlElmdscr_add (edP); mdlElmdscr_freeAll (&edP); }
You can drop this SmartSurface to get these arcs and lines or use mdlKISolid_getEdgeList to get them.
HTH, Yongan
Unknown said:mdlKISolid_bodyToElement (&edP, pBody, TRUE, -1, NULL, ACTIVEMODEL)
1. The third parameter "wireframe" has the following meaning which I found from MicroStation help file. Maybe it isn't the normal meaning as we expected.
You can try to change this parameter from TRUE to FALSE, it will create Surface (type=18) element not a SmartSurface.
2. Actually, mdlKISolid_bodyToElement call mdlKISolid_bodyToElementD with the last parameter set to TRUE. Thanks for your reminder.
Yongan: thanks for your detective work! It's very helpful to understand those details.
Unknown said:Change this parameter from TRUE to FALSE, it will create Surface (type=18) element not a SmartSurface
Well, I would not have guessed that from the MDL documentation 8-)
Hi Yongan,
Thank you very much for your reply. I've tried the code snippet given by you. Yes, that's what I needed. But, I've one concern with this approach. Since the given test case yields a single boundary, I can assume all the set of arcs and lines form a single loop / boundary. If there are multiple boundaries, then how can I distinguish which set of curves form which boundary?
Hi Kaab,
If you have multiple boundaries you can use mdlKISolid_xxx functions to distinguish them as my below snippet:
MSElementDescrP edP = NULL; KIBODY *pBody = NULL; if(SUCCESS != mdlAssoc_getElementDescr(&edP, NULL, 555, ACTIVEMODEL, FALSE)) return -1; mdlKISolid_elementToBody (&pBody, edP, ACTIVEMODEL); mdlElmdscr_freeAll (&edP); edP = NULL; if (SUCCESS == mdlKISolid_bodyToElementD (&edP, pBody, TRUE, -1, NULL, ACTIVEMODEL, TRUE)) { int faceCnt; KIENTITY_LIST *pFaceList = NULL; mdlKISolid_listCreate (&pFaceList); mdlKISolid_getFaceList (pFaceList, pBody); mdlKISolid_listCount (&faceCnt, pFaceList); for (int i=0; i<faceCnt; i++) { KIFACE *pFace; mdlKISolid_listNthEl (&pFace, pFaceList, i); if (SUCCESS == mdlKISolid_faceToElement (&edP, pFace, TRUE, -1, NULL, ACTIVEMODEL)) { mdlElmdscr_setSymbology (edP, (UInt32 *)&i, NULL, NULL, NULL); mdlElmdscr_add (edP); mdlElmdscr_freeAll (&edP); edP = NULL; } } mdlKISolid_listDelete (&pFaceList); mdlKISolid_freeBody (pBody); }I added another trim loop to your Bspline surface and the result is shown as below. Please note: the black and blue color are somewhat close.
MSElementDescrP edP = NULL; KIBODY *pBody = NULL; if(SUCCESS != mdlAssoc_getElementDescr(&edP, NULL, 555, ACTIVEMODEL, FALSE)) return -1; mdlKISolid_elementToBody (&pBody, edP, ACTIVEMODEL); mdlElmdscr_freeAll (&edP); edP = NULL; if (SUCCESS == mdlKISolid_bodyToElementD (&edP, pBody, TRUE, -1, NULL, ACTIVEMODEL, TRUE)) { int faceCnt; KIENTITY_LIST *pFaceList = NULL; mdlKISolid_listCreate (&pFaceList); mdlKISolid_getFaceList (pFaceList, pBody); mdlKISolid_listCount (&faceCnt, pFaceList); for (int i=0; i<faceCnt; i++) { KIFACE *pFace; mdlKISolid_listNthEl (&pFace, pFaceList, i); if (SUCCESS == mdlKISolid_faceToElement (&edP, pFace, TRUE, -1, NULL, ACTIVEMODEL)) { mdlElmdscr_setSymbology (edP, (UInt32 *)&i, NULL, NULL, NULL); mdlElmdscr_add (edP); mdlElmdscr_freeAll (&edP); edP = NULL; } } mdlKISolid_listDelete (&pFaceList); mdlKISolid_freeBody (pBody); }
HTH,Yongan
Answer Verified By: kaab
Unknown said: If there are multiple boundaries, then how can I distinguish which set of curves form which boundary?
As each face is processed, it yields a boundary object that is then converted to an element descriptor chain. The chain is added to the active model in Yongan's example.
You can identify those boundaries in several ways:
Unknown said: I added another trim loop to your Bspline surface and the result is shown as below. Please note: the black and blue color are somewhat close.
I added another trim loop to your Bspline surface and the result is shown as below. Please note: the black and blue color are somewhat close.
Thank you very much for your detailed explanation with screenshots. That's what I required exactly.
Unknown said: As each face is processed, it yields a boundary object that is then converted to an element descriptor chain. The chain is added to the active model in Yongan's example. You can identify those boundaries in several ways: If you want to work in-memory with the boundaries, add your identification data to the descriptor chain in pDescriptor->h.userData1 If you want to work with the boundaries after they've been added to the model, you could use one of these: record the file position (returned by mdlElmdscr_add) record the Element ID
Thank you for your explanation of the logic and suggestions.