Hi everybody,
I'm experiencing a problem drawing an AcDbLine.
I have an entity (HS00Pipe) which inerhits from the AcdbLine entity.
When I draw it I use the following procedure:
Acad::ErrorStatus Err; ads_point pt1, pt2; AcGePoint3d pt3d1, pt3d2; //primo punto del tubo () if ( acedGetPoint(NULL, _T("Specificare primo punto:"), pt1) != RTNORM ) return; if ( acedGetPoint(pt1, _T("Specificare secondo punto:"), pt2) != RTNORM ) return; pt3d1 = asPnt3d(pt1); pt3d2 = asPnt3d(pt2); AcGeVector3d v = pt3d1 - pt3d2; AcDbBlockTable *pBlockTable; if ( acdbHostApplicationServices()->workingDatabase()->getBlockTable (pBlockTable, AcDb::kForRead) == Acad::eOk ) { // Get the Model Space record and open it for write. This will be the owner of the new employee entity. AcDbBlockTableRecord *pSpaceRecord; if ( pBlockTable->getAt (ACDB_MODEL_SPACE, pSpaceRecord, AcDb::kForWrite) == Acad::eOk ) { HS00Pipe *pLine = new HS00Pipe(pt3d1, pt3d2); AcGePoint3d pt3d1_test, pt3d2_test; pLine->getStartPoint(pt3d1_test); pLine->getEndPoint(pt3d2_test); CAcModuleResourceOverride res; CNodeProperty CProp; //CProp.m_ID = 0; CProp.m_ID_AutoCADProductType = Enum::AutoCADProductTypeEnum::PIPE; CProp.m_ID_SAPProductGroup = 0; CProp.m_ID_Parent = 0; CProp.m_Name.Format(p->get_ShortName() + _T("-%04d"), DocVars.docData().globalobjectcounter++); CProp.m_Length = plugin_settings->ScaleFromACADUnitsToMeters( v.length()); // gestione scala CProp.m_ID_Drafting_Status = Enum::DraftingStatusEnum::DRAFT; CProp.m_ID_Gas = ID_Gas; CProp.m_ID_WardSizing = 0; if (CProp.DoModal() == IDOK) { acutPrintf (_T("\n Aggiornamento nodo\n")) ; // Append pEnt to Model Space, then close it and the Model Space record. AcDbObjectId idObj; pSpaceRecord->appendAcDbEntity (idObj, pLine); pLine->close (); pSpaceRecord->close () ; if ( (Err = acdbOpenAcDbObject ((AcDbObject*&)pLine, idObj, AcDb::kForWrite)) != Acad::eOk ) { acutPrintf (_T("\n Errore apertura pLine. (Err=%d)\n"), Err) ; return; } HS00NodeDetails *pNodeDetails = new HS00NodeDetails; Logic::CopyDataFromFormToNodeDetail(pNodeDetails, &CProp); //aggiungo il fattore di scala per ridimensionare il testo sulla linea pNodeDetails->m_scale_factor = ((float)plugin_settings->ScaleFactorFrom/(float)plugin_settings->ScaleFactorTo); if ((Err = DraftingTool_SetNodeDetails(pLine, AcDb::kForWrite, pNodeDetails)) == Acad::eOk) { acutPrintf (_T("\n Oggetto inserito.\n")); pNodeDetails->close(); } else { acutPrintf (_T("\n Impossibile aggiungere l'oggetto. (Err=%d)\n"), Err); delete pNodeDetails; } pLine->close(); } else delete pLine; pSpaceRecord->close () ; } pBlockTable->close () ; }
It worked always well with lots of dwg files, but now, trying to draw an HS00Pipe on a certain dwg file I get the line moved after the drawing.
I think it could be a problem dued from a particular setting on that dwg file or I missed to handle/override some stuffs inerithing from the acdbline entity.
I tried to draw an acdbline with the LINE command and it worked well without moving the line at the end of the drawing.
For this reason I think that my entity doesn't handle some offset or particular setting that the acdbline handle well.
Drawing my entity on another dwg file works well, so it should be the behaviour of my entity on that dwg file.
Here below my entity source code:
#include "StdAfx_NodeDetails.h" //----------------------------------------------------------------------------- Adesk::UInt32 HS00Pipe::kCurrentVersionNumber =1 ; //----------------------------------------------------------------------------- ACRX_DXF_DEFINE_MEMBERS ( HS00Pipe, AcDbLine, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation, HS00PIPE, HS00NODEDETAILSAPP |Product Desc: A description for your object |Company: Your company name |WEB Address: Your company WEB site address ) //----------------------------------------------------------------------------- HS00Pipe::HS00Pipe () : AcDbLine () { } HS00Pipe::HS00Pipe(const AcGePoint3d & start, const AcGePoint3d & end): AcDbLine (start, end) { } HS00Pipe::~HS00Pipe () { } //----------------------------------------------------------------------------- //----- AcDbObject protocols //- Dwg Filing protocol Acad::ErrorStatus HS00Pipe::dwgOutFields (AcDbDwgFiler *pFiler) const { assertReadEnabled () ; //----- Save parent class information first. Acad::ErrorStatus es =AcDbLine::dwgOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; //----- Object version number needs to be saved first if ( (es =pFiler->writeUInt32 (HS00Pipe::kCurrentVersionNumber)) != Acad::eOk ) return (es) ; //----- Output params //..... return (pFiler->filerStatus ()) ; } Acad::ErrorStatus HS00Pipe::dwgInFields (AcDbDwgFiler *pFiler) { assertWriteEnabled () ; //----- Read parent class information first. Acad::ErrorStatus es =AcDbLine::dwgInFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; //----- Object version number needs to be read first Adesk::UInt32 version =0 ; if ( (es =pFiler->readUInt32 (&version)) != Acad::eOk ) return (es) ; if ( version > HS00Pipe::kCurrentVersionNumber ) return (Acad::eMakeMeProxy) ; //- Uncomment the 2 following lines if your current object implementation cannot //- support previous version of that object. //if ( version < HS00Pipe::kCurrentVersionNumber ) // return (Acad::eMakeMeProxy) ; //----- Read params //..... return (pFiler->filerStatus ()) ; } //- Persistent reactor callbacks void HS00Pipe::openedForModify (const AcDbObject *pDbObj) { assertReadEnabled () ; AcDbLine::openedForModify (pDbObj) ; } void HS00Pipe::cancelled (const AcDbObject *pDbObj) { assertReadEnabled () ; AcDbLine::cancelled (pDbObj) ; } void HS00Pipe::objectClosed (const AcDbObjectId objId) { assertReadEnabled () ; AcDbLine::objectClosed (objId) ; } void HS00Pipe::goodbye (const AcDbObject *pDbObj) { assertReadEnabled () ; AcDbLine::goodbye (pDbObj) ; } void HS00Pipe::copied (const AcDbObject *pDbObj, const AcDbObject *pNewObj) { assertReadEnabled () ; AcDbLine::copied (pDbObj, pNewObj) ; } void HS00Pipe::erased (const AcDbObject *pDbObj, Adesk::Boolean bErasing) { assertReadEnabled () ; AcDbLine::erased (pDbObj, bErasing) ; } void HS00Pipe::modified (const AcDbObject *pDbObj) { assertReadEnabled () ; AcDbLine::modified (pDbObj) ; } void HS00Pipe::modifiedGraphics (const AcDbEntity *pDbEnt) { assertReadEnabled () ; AcDbLine::modifiedGraphics (pDbEnt) ; } void HS00Pipe::modifiedXData (const AcDbObject *pDbObj) { assertReadEnabled () ; AcDbLine::modifiedXData (pDbObj) ; } void HS00Pipe::subObjModified (const AcDbObject *pMainbObj, const AcDbObject *pSubObj) { assertReadEnabled () ; AcDbLine::subObjModified (pMainbObj, pSubObj) ; } void HS00Pipe::modifyUndone (const AcDbObject *pDbObj) { assertReadEnabled () ; AcDbLine::modifyUndone (pDbObj) ; } void HS00Pipe::reappended (const AcDbObject *pDbObj) { assertReadEnabled () ; AcDbLine::reappended (pDbObj) ; } void HS00Pipe::unappended (const AcDbObject *pDbObj) { assertReadEnabled () ; AcDbLine::unappended (pDbObj) ; } //Acad::ErrorStatus HS00Pipe::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType,const AcGePlane& projPlane, AcGePoint3dArray& points,Adesk::GsMarker thisGsMarker , Adesk::GsMarker otherGsMarker) const //{ // assertReadEnabled () ; // return AcDbLine::subIntersectWith(pEnt, intType,projPlane, points,thisGsMarker , otherGsMarker); //} // //Acad::ErrorStatus HS00Pipe::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType, AcGePoint3dArray& points, Adesk::GsMarker thisGsMarker ,Adesk::GsMarker otherGsMarker ) const //{ // assertReadEnabled () ; // return AcDbLine::subIntersectWith( pEnt,intType, points, thisGsMarker, otherGsMarker ); //} //gestione comando _FILLET Acad::ErrorStatus HS00Pipe::extend(double param) { assertWriteEnabled(); AcGePoint3d startPnt(startPoint()), endPnt(endPoint()); double norm = startPnt.distanceTo(endPnt); AcGeLine3d geLine (startPnt, endPnt); AcGePointOnCurve3d ponc(geLine); if (param > 0.0) setEndPoint(ponc.point(param / norm)); else setStartPoint(ponc.point(param / norm)); return Acad::eOk; } //----------------------------------------------------------------------------- //----- AcDbEntity protocols Adesk::Boolean HS00Pipe::subWorldDraw (AcGiWorldDraw *mode) { //scrivo sul tubo il diametro interno e il diametro esterno assertReadEnabled () ; AcDbLine::subWorldDraw (mode); int internal_diameter; int external_diameter; double scale_factor=1.0; AcString pipe_name; AcString pipe_tag; //apro il dictionary se riesco/////////////////////////////////////////////////// AcDbObjectId dict_id; if ( (dict_id = this->extensionDictionary()) == AcDbObjectId::kNull ) return Adesk::kTrue; AcDbDictionary * pNodeDict = NULL; if (GetExtensionDictionary(this, _T("HS00_NODE_DICTIONARY"), AcDb::kForRead, pNodeDict) == Acad::eOk) { AcDbObject * pDictNode = NULL; if (GetDictionaryNode(pNodeDict, _T("DETAILS"), AcDb::kForWrite, pDictNode) == Acad::eOk) { // Check it is a HS00NodeDetails object HS00NodeDetails *pNodeDetails = HS00NodeDetails::cast(pDictNode); if (pNodeDetails) { internal_diameter = pNodeDetails->m_Internal_Diameter; external_diameter = pNodeDetails->m_External_Diameter; scale_factor= scale_factor*pNodeDetails->m_scale_factor; pipe_name = pNodeDetails->m_Name; if(pNodeDetails->m_ID_Tag > 0) pipe_tag = pNodeDetails->m_TagName; else pipe_tag = _T(""); pNodeDetails->close(); } pDictNode->close(); } pNodeDict->close(); } AcGePoint3d position; AcGeVector3d norm; AcGeVector3d direction; double height,width=1.0, oblique = 0.0; TCHAR buffer [255] = _T(""); height =0.1; AcGePoint3d ptStart, ptEnd; getStartPoint(ptStart); getEndPoint(ptEnd); direction = ptEnd - ptStart; norm = normal(); position = ptStart + (ptEnd - ptStart) / 2.0; position.x += 0.04; position.y += 0.04; //_stprintf (buffer, _T("%s ø %dx%d"),pipe_name.constPtr() , internal_diameter, external_diameter); //stampo sul tubo il tag e i diametri if(pipe_tag.isEmpty()) _stprintf (buffer, _T("ø %dx%d") , internal_diameter, external_diameter); else _stprintf (buffer, _T("[%s] ø %dx%d") , pipe_tag.constPtr() , internal_diameter, external_diameter); mode->geometry().text(position, norm, direction, height, width, oblique, buffer); //disegno la freccia sul pundo di fine linea////////////////////////////////////////////////////////////////////////////////////////// //AcGePoint3d arrow_p1, arrow_p2; //AcGeVector3d arrow_v1; //arrow_v1 = ptStart - ptEnd; //arrow_v1.transformBy(AcGeMatrix3d::scaling(0.02,ptEnd)); //riscalo il vettore (faccio la freccia lunga il 10% della linea) //arrow_v1.transformBy(AcGeMatrix3d::rotation(0.5,norm,ptEnd)); //circa 30° //arrow_p1 = AcGePoint3d(arrow_v1.x + ptEnd.x,arrow_v1.y + ptEnd.y,arrow_v1.z + ptEnd.z); //arrow_v1.transformBy(AcGeMatrix3d::rotation(-1,norm,ptEnd)); //arrow_p2 = AcGePoint3d(arrow_v1.x + ptEnd.x,arrow_v1.y + ptEnd.y,arrow_v1.z + ptEnd.z); //AcDbLine l1(ptEnd,arrow_p1), l2(ptEnd,arrow_p2); //l1.setLayer(this->layer()); //l2.setLayer(this->layer()); //mode->geometry().draw(&l1); //mode->geometry().draw(&l2); //mode->geometry().draw(&AcDbLine(arrow_p1,arrow_p2)); //----- Returns Adesk::kTrue to not call viewportDraw() return (Adesk::kTrue) ; } Adesk::UInt32 HS00Pipe::subSetAttributes (AcGiDrawableTraits *traits) { assertReadEnabled () ; return (AcDbLine::subSetAttributes (traits)) ; } //- Osnap points protocol Acad::ErrorStatus HS00Pipe::subGetOsnapPoints ( AcDb::OsnapMode osnapMode, int gsSelectionMark, const AcGePoint3d &pickPoint, const AcGePoint3d &lastPoint, const AcGeMatrix3d &viewXform, AcGePoint3dArray &snapPoints, AcDbIntArray &geomIds) const { assertReadEnabled () ; return (AcDbLine::subGetOsnapPoints (osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds)) ; } Acad::ErrorStatus HS00Pipe::subGetOsnapPoints ( AcDb::OsnapMode osnapMode, int gsSelectionMark, const AcGePoint3d &pickPoint, const AcGePoint3d &lastPoint, const AcGeMatrix3d &viewXform, AcGePoint3dArray &snapPoints, AcDbIntArray &geomIds, const AcGeMatrix3d &insertionMat) const { assertReadEnabled () ; return (AcDbLine::subGetOsnapPoints (osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds, insertionMat)) ; } //- Grip points protocol Acad::ErrorStatus HS00Pipe::subGetGripPoints ( AcGePoint3dArray &gripPoints, AcDbIntArray &osnapModes, AcDbIntArray &geomIds ) const { assertReadEnabled () ; //----- This method is never called unless you return eNotImplemented //----- from the new getGripPoints() method below (which is the default implementation) return (AcDbLine::subGetGripPoints (gripPoints, osnapModes, geomIds)) ; } Acad::ErrorStatus HS00Pipe::subMoveGripPointsAt (const AcDbIntArray &indices, const AcGeVector3d &offset) { assertWriteEnabled () ; //----- This method is never called unless you return eNotImplemented //----- from the new moveGripPointsAt() method below (which is the default implementation) return (AcDbLine::subMoveGripPointsAt (indices, offset)) ; } Acad::ErrorStatus HS00Pipe::subGetGripPoints ( AcDbGripDataPtrArray &grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d &curViewDir, const int bitflags ) const { assertReadEnabled () ; //----- If you return eNotImplemented here, that will force AutoCAD to call //----- the older getGripPoints() implementation. The call below may return //----- eNotImplemented depending of your base class. return (AcDbLine::subGetGripPoints (grips, curViewUnitSize, gripSize, curViewDir, bitflags)) ; } Acad::ErrorStatus HS00Pipe::subMoveGripPointsAt ( const AcDbVoidPtrArray &gripAppData, const AcGeVector3d &offset, const int bitflags ) { assertWriteEnabled () ; //----- If you return eNotImplemented here, that will force AutoCAD to call //----- the older getGripPoints() implementation. The call below may return //----- eNotImplemented depending of your base class. return (AcDbLine::subMoveGripPointsAt (gripAppData, offset, bitflags)) ; } Acad::ErrorStatus HS00Pipe::GetExtensionDictionary(const AcDbObject * pObj, const TCHAR * strDictName, AcDb::OpenMode mode, AcDbDictionary *& pNodeDict) { // check if (pObj == NULL || strDictName == NULL) return Acad::eInvalidInput; Acad::ErrorStatus Err; // Get the Ext. Dictionary AcDbObjectId idO ; if ( (idO = pObj->extensionDictionary()) == AcDbObjectId::kNull ) { // Nothing to do //acutPrintf (_T("\nIl nodo non ha un extension dictionary.")) ; return Acad::eInvalidObjectId; //TBD } // If erased, nothing to do AcDbDictionary *pExtDict; if ( (Err = acdbOpenAcDbObject ((AcDbObject *&)pExtDict, idO, AcDb::kForRead, Adesk::kFalse)) != Acad::eOk ) { acutPrintf (_T("\nErrore durante l'apertura dell'extension dictionary. (Err=%d)"), Err) ; return Err; } // See if our dictionary is already there AcDbObject *pO; if ( (Err = pExtDict->getAt(strDictName, idO)) == Acad::eKeyNotFound ) { // Nothing to do if not pExtDict->close(); acutPrintf (_T("\nImpossibile trovare il dictionary '%s'. (Err=%d)"), strDictName, Err); return Err; } else { // Open dictionary for read/write if it is already there if ( (Err = acdbOpenAcDbObject (pO, idO, mode)) != Acad::eOk ) { pExtDict->close () ; acutPrintf (_T("\nImpossibile aprire il dictionary '%s' in lettura. (Err%d)"), strDictName, Err); return Err; } // Check if someone has else has created an entry with our name // that is not a dictionary. if ( (pNodeDict =AcDbDictionary::cast (pO)) == NULL ) { pO->close (); pExtDict->close (); acutPrintf (_T("\n'%s' non è un dictionary"), strDictName); return Acad::eNotImplementedYet; //TBD } } pExtDict->close(); return Acad::eOk; } Acad::ErrorStatus HS00Pipe::GetDictionaryNode(const AcDbDictionary * pDict, const TCHAR * strNodeName, AcDb::OpenMode mode, AcDbObject *& pDictNode) { // check if (pDict == NULL || strNodeName == NULL) return Acad::eInvalidInput; Acad::ErrorStatus Err; // Check if a record with this key is already there AcDbObjectId idO ; if ( (Err = pDict->getAt(strNodeName, idO)) != Acad::eOk ) { // Nothing to do //acutPrintf (_T("\nImpossibile trovare il nodo '%s'. (Err=%d)"), strNodeName, Err); return Acad::eInvalidObjectId; //TBD } // Open the object with the requested mode (Read or Write) if ( (Err = acdbOpenAcDbObject(pDictNode, idO, mode)) != Acad::eOk ) { acutPrintf (_T("\nImpossibile aprire il nodo '%s' in lettura. (Err=%d)"), strNodeName, Err); return Acad::eNotImplementedYet; //TBD } return Acad::eOk; } AcGePoint3d HS00Pipe::GetOpposedPoint(AcGePoint3d input_point) {//ritorna il punto opposto a quello fornito serve per evitare di avere tubi direzionali. if(input_point == startPoint()) return endPoint(); else return startPoint(); }
Thanks for your help.
Have a good day,
Massimo.
The acedGetPoint() function returns a point in UCS, however AcDbLine expects points in WCS. You need to convert your points to WCS:
AcGeMatrix3d mxUCS; acdbUcsMatrix(mxUCS); pt3d1.transformBy(mxUCS); pt3d2.transformBy(mxUCS);
Dear Sir:
So while try to use a Line to intersectwith another Line,the error code:"eNotImplementedYet", also means I have to transform the two Lines before they intersected?
If it is, how can I transform them?
This means that the method subIntersectWith is not implemented. If it is a Custom Entity then you have to implement it.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | 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
> how can I implement it. (it = intersectWith() )
You can't - unless you implemented the class yourself.
If you want to implement the behaviour of intersectWith() in your own class, you have to overwrite the virtual methods subIntersectWith(). For details refer to the ObjectARX Developer's Guide. See "Intersecting a Custom Entity with Another Entity" and "Intersecting with Other Entities".
Otherwise you can try to call the baseclass explecitely: pLine->AcDbLine::intersectWith(pOther).