Hi everybody,
I'm experiencing a problem with a specific DWG file and the call to the acedSSGet function.
I have an algorithm that start from a root object and discover a tree structure selecting all the child objects placed on the parent object.
Code is here belove:
std::list<Recursion::RecursionChildElementContainer> DraftingTool_GetChildrenObjectsOrdered(AcDbObjectId oid, int ID_Gas, AcGePoint3d input_point) { std::list<Recursion::RecursionChildElementContainer> r = std::list<Recursion::RecursionChildElementContainer>(); AcDbEntity * pEnt; AcDbBlockReference * pBlockref; HS00Pipe * pPipe; AcGePoint3d point1, point2; //intersection points //open the entity if (acdbOpenAcDbEntity(pEnt,oid,AcDb::kForRead) != Acad::eOk) return r; pBlockref = AcDbBlockReference::cast(pEnt); pPipe = HS00Pipe::cast(pEnt); if(pBlockref) { point1 = DraftingTool_BlockGetOutputPoint(pBlockref); point2 = point1; pBlockref->close(); } else if(pPipe) { point1 = pPipe->startPoint(); point2 = pPipe->endPoint(); pPipe->close(); } if(pEnt) pEnt->close(); //get children objects ads_name ssname, ent; ads_point ads_point1,ads_point2; ads_point1[X] = point1.x; ads_point1[Y] = point1.y; ads_point1[Z] = point1.z; ads_point2[X] = point2.x; ads_point2[Y] = point2.y; ads_point2[Z] = point2.z; int ssget_return_code = 0; ssget_return_code = acedSSGet(_T("_C"), ads_point1, ads_point2 , NULL, ssname); long length = 0; //number of selected entities if ((acedSSLength( ssname, &length ) != RTNORM)) acedSSFree( ssname ); //free the selection. for (long i = 0; i < length; i++) { //provo l'apertura della entity AcDbObjectId selected_oid = AcDbObjectId::kNull; AcDbEntity * selected_pEnt = NULL; HS00NodeDetails * selected_pNodeDetails = NULL; AcDbBlockReference * selected_pBlock = NULL; HS00Pipe * selected_pPipe = NULL; AcGePoint3d touch_point; if (acedSSName(ssname , i , ent) != RTNORM) continue; if (acdbGetObjectId(selected_oid , ent) != Acad::eOk) continue; if (acdbOpenAcDbEntity(selected_pEnt , selected_oid , AcDb::kForRead) != Acad::eOk) { if(selected_pEnt) selected_pEnt->close(); continue; } bool bProcessNode = true; selected_pBlock = AcDbBlockReference::cast(selected_pEnt); selected_pPipe = HS00Pipe::cast(selected_pEnt); if(selected_pBlock) //the selected entity is a block. {//this block has to be considered only if its input point is on the selection line AcGePoint3d selected_block_input_point = AcGePoint3d(); selected_block_input_point = DraftingTool_BlockGetInputPoint(selected_pBlock); bProcessNode &= DraftingTool_IsPointOnLine(point1,point2,selected_block_input_point); if(bProcessNode) touch_point = selected_block_input_point; selected_pBlock->close(); } if(selected_pPipe) //the selected entity is a pipe {//this pipe has to be considered only if it has its start point on the selection line AcGePoint3d selected_pipe_start_point = AcGePoint3d(); AcGePoint3d selected_pipe_end_point = AcGePoint3d(); selected_pipe_start_point = selected_pPipe->startPoint(); selected_pipe_end_point = selected_pPipe->endPoint(); if(point1 == point2) { } else { //XOR - check for overlapped pipes bProcessNode &= ( DraftingTool_IsPointOnLine(point1,point2,selected_pipe_start_point) != DraftingTool_IsPointOnLine(point1,point2,selected_pipe_end_point)); } if(bProcessNode) { if(DraftingTool_IsPointOnLine(point1,point2,selected_pipe_start_point)) touch_point = selected_pipe_start_point; else touch_point = selected_pipe_end_point; } selected_pPipe->close(); } //check if the selected object is on the right layer if (DraftingTool_GetNodeDetails(selected_pEnt, AcDb::kForRead, selected_pNodeDetails) != Acad::eOk) bProcessNode &= false; if(selected_pNodeDetails) { bProcessNode &= (selected_pNodeDetails->m_ID_Gas == ID_Gas); selected_pNodeDetails->close(); } if(selected_pEnt) selected_pEnt->close(); //it doesn't return brothers but only childreen objects bProcessNode &= (touch_point != input_point); if(bProcessNode) { Recursion::RecursionChildElementContainer rcec; rcec._ObjId = selected_oid; //calcolo distanza input_point - touch point rcec._DistanceFromInputPoint = input_point.distanceTo(touch_point); rcec._TouchPoint = touch_point; r.push_front(rcec); } } // close the selection set acedSSFree( ssname ); //sort based on the distance from input point r.sort(RecursionChildElementContainer_DistanceSorter); return r; }
To select the child object I have to use the acedSSGet function with the following parameter:
acedSSGet(_T("_C"), ads_point1, ads_point2 , NULL, ssname);
The function returns RTERROR -5001.
My application works well with other dwg files, but not with that one.
Could it be a problem of UCS WCS transformation? Or, maybe some weird setting of the file?
Is there a way to investigate better? maybe with arxdbg? what should I do to understand better the problem?
Is there a way to call the acedssget from the acad console to prove that my arx application is not the problem?
Thank you so much guys!
Have a good day!
Massimo
Hi,
I noticed that the function works well if:
1. right click on the origin in the bottom left part of the drawing window
2. click on "Global"
then the acedssget works well, so I definitely think that it's a problem of WCS UCS conversion,
So I changed my code in the following way, but the problem is still there!
std::list<Recursion::RecursionChildElementContainer> DraftingTool_GetChildrenObjectsOrdered(AcDbObjectId oid, int ID_Gas, AcGePoint3d input_point) { std::list<Recursion::RecursionChildElementContainer> r = std::list<Recursion::RecursionChildElementContainer>(); AcDbEntity * pEnt; AcDbBlockReference * pBlockref; HS00Pipe * pPipe; AcGePoint3d point1, point2; if (acdbOpenAcDbEntity(pEnt,oid,AcDb::kForRead) != Acad::eOk) return r; pBlockref = AcDbBlockReference::cast(pEnt); pPipe = HS00Pipe::cast(pEnt); if(pBlockref) { point1 = DraftingTool_BlockGetOutputPoint(pBlockref); point2 = point1; pBlockref->close(); } else if(pPipe) { point1 = pPipe->startPoint(); point2 = pPipe->endPoint(); pPipe->close(); } if(pEnt) pEnt->close(); ads_name ssname, ent; ads_point ads_point1,ads_point2; //conversione coordinate da UCS (User Coordinate System) a WCS (World Coordinate System)//////////////////// AcGeMatrix3d mxUCS; acdbUcsMatrix(mxUCS); point1.transformBy(mxUCS); point2.transformBy(mxUCS); //////////////////////////////////////////////////////////////////////////////////////////////////////////// ads_point1[X] = point1.x; ads_point1[Y] = point1.y; ads_point1[Z] = point1.z; ads_point2[X] = point2.x; ads_point2[Y] = point2.y; ads_point2[Z] = point2.z; int ssget_return_code = 0; ssget_return_code = acedSSGet(_T("_C"), ads_point1, ads_point2 , NULL, ssname); long length = 0; if ((acedSSLength( ssname, &length ) != RTNORM))
Maybe, should I use a different conversion?
Thanks for your help,
Massimo
What coordinate system are your points in? They need to be in UCS coordinates for sending to acedSSGet. The code you added converts points from UCS to WCS, so it is definitely wrong. If your points are originally in WCS, you need to invert the matrix in order to convert them to UCS.
Are you know ads_point1 and ads_point2, used in calling
acedSSGet(_T("_C"), ads_point1, ads_point2 , NULL, ssname);
have to be visible in active viewport?
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Yes,
I know acedssget works only with objects visible on the viewport.
I already had that crazy issue 🙂
I tried also applying the inverse matrix but it doesn't work..
What to do?
Thanks,
Massimo
@Anonymous wrote:
I tried also applying the inverse matrix but it doesn't work..
What to do?
I think you have to do two transformation:
1) WCS -> DCS
2) DCS -> UCS
Both transformation you have to do with help of acedTrans function. Read this topic: http://forums.autodesk.com/t5/objectarx/forming-a-crossing-polygon-in-dcs-for-passing-to-acedssget/td-p/4341617
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Hum,
why passing through the DCS, should it fix the issue?
I already tried to tranform from the WCS to UCS and it didn't solved the issue...
Thanks for your time.
@Anonymous wrote:I tried also applying the inverse matrix but it doesn't work..
You should know by now that "It doesn't work" is not appropriate in a technical forum. Did your computer overheat and evaporate in a cloud of smoke? Did you get Windows' Blue screen of death? Probably not, but we can only guess. My guess is that it did exactly what you told it to do. You haven't made any mention about your original points, so perhaps you missed that part of my reply. They must be converted to WCS before you can perform a WCS->UCS conversion.