#include "stdafx.h" #include "dbobjptr.h " #include "CoreTools.h" #include "acedsubsel.h" #pragma region brep-include #include "acutads.h" #include "acedads.h" #include "string.h" #include "adscodes.h" #include "brent.h" #include "brbrep.h" #include "dbmain.h" #include "geextc3d.h" #include "brface.h" #include "brvtx.h" #include "dbents.h" #include "geassign.h" #include "geextc2d.h" #include "gexbndsf.h" #include "aced.h" #include "acestext.h" #include "actrans.h" #include "adeskabb.h" #include "brbctrav.h" #include "brbvtrav.h" #include "bredge.h" #include "brfltrav.h" #include "brgbl.h" #include "brletrav.h" #include "brlvtrav.h" #include "dbsol3d.h" #include "dbsymtb.h" #include "gelnsg3d.h" #include "gemat3d.h" #include "genurb3d.h" #include "genurbsf.h" #include "geray3d.h" #include "ol_errno.h" #include "adesk.h" #include "adslib.h" #include "brbetrav.h" #include "brbftrav.h" #include "brbstrav.h" #include "brcstrav.h" #include "brelem2d.h" #include "breltrav.h" #include "brentrav.h" #include "brhit.h" #include "brloop.h" #include "brmetrav.h" #include "brprops.h" #include "brm2dctl.h" #include "brmesh2d.h" #include "brnode.h" #pragma endregion #include "BrepOper.h" #include "KTCADUtilityEx.h" #include "KTCADUtility.h" #pragma region sh-entity #include "AecDbBDPipeBase.h" #include "AecDbWall.h" #include "AecDbSlab.h" #include "AecDbColumn.h" #include "AecDbBeam.h" #include "AecDbEwEquipment.h" #pragma endregion namespace { const double kPi = 3.14159265358979323846; const double kTwoPi = 6.28318530717958647692; const double kHalfPi = 1.57079632679489661923; void errorReport(AcBr::ErrorStatus errorCode) { switch (errorCode) { case(AcBr::eBrepChanged): acutPrintf(ACRX_T(" Brep Changed\n")); break; case(AcBr::eUnsuitableTopology): acutPrintf(ACRX_T(" Unsuitable Topology\n")); break; case(AcBr::eDegenerateTopology): acutPrintf(ACRX_T(" Degenerate Topology\n")); break; case(AcBr::eUninitialisedObject): acutPrintf(ACRX_T(" Uninitialised Object\n")); break; default: acutPrintf(ACRX_T(" AutoCAD Error Code: %d\n"), errorCode); acadErrorStatusText((Acad::ErrorStatus)errorCode); break; } return; } // Add the given entity to the current Database Acad::ErrorStatus addToDatabase(AcDbEntity* pEnt, AcDbObjectId& objId) { Acad::ErrorStatus acadReturnValue = Acad::eOk; AcDbBlockTable* pBlockTable; AcDbBlockTableRecord* pSpaceRecord; AcDbDatabase *pCurDwg = acdbHostApplicationServices()->workingDatabase(); if (pCurDwg==NULL) return Acad::eNoDatabase; if ((acadReturnValue = pCurDwg->getBlockTable(pBlockTable, AcDb::kForRead)) != Acad::eOk) { acutPrintf(ACRX_T("\n acdbCurDwg()->getBlockTable() failed")); return acadReturnValue; } if ((acadReturnValue = pBlockTable->getAt(ACDB_MODEL_SPACE, pSpaceRecord, AcDb::kForWrite)) != Acad::eOk) { acutPrintf(ACRX_T("\n AcDbBlockTable::getAt() failed")); return acadReturnValue; } // close the block table object if ((acadReturnValue = pBlockTable->close()) != Acad::eOk) { acutPrintf(ACRX_T("\n AcDbBlockTable::close() failed")); return acadReturnValue; } // append the entity to the display list if ((acadReturnValue = pSpaceRecord->appendAcDbEntity(objId, pEnt)) != Acad::eOk) { acutPrintf(ACRX_T("\n AcDbBlockTableRecord::appendAcDbEntity() failed")); return acadReturnValue; } // close the block table record object if ((acadReturnValue = pSpaceRecord->close()) != Acad::eOk) { acutPrintf(ACRX_T("\n AcDbBlockTableRecord::close() failed")); return acadReturnValue; } return acadReturnValue; } Acad::ErrorStatus dbOpenTransaction(Adesk::Boolean& ownTransaction) { Acad::ErrorStatus acadReturnValue = Acad::eOk; // Open a new transaction only when there is not an existing one. if (actrTransactionManager->numActiveTransactions() == 0) { if (actrTransactionManager->startTransaction() == NULL) { return Acad::eNoActiveTransactions; } else ownTransaction = kTrue; } else ownTransaction = kFalse; return acadReturnValue; } // Note: This function conditionally closes a transaction. Acad::ErrorStatus dbCloseTransaction(Adesk::Boolean& ownTransaction) { Acad::ErrorStatus acadReturnValue = Acad::eOk; // Close only in the case where we own the transaction. if (ownTransaction) acadReturnValue = actrTransactionManager->endTransaction(); return acadReturnValue; } // Note: This function conditionally aborts a transaction, which invokes UNDO. Acad::ErrorStatus dbAbortTransaction(Adesk::Boolean& ownTransaction) { Acad::ErrorStatus acadReturnValue = Acad::eOk; // Abort only in the case where we own the transaction. if (ownTransaction) acadReturnValue = actrTransactionManager->abortTransaction(); return acadReturnValue; } void objIds2SubPath(const AcDbObjectIdArray &objIdList, const AcDb::SubentType &subType, const AcDbFullSubentPath *subentIds, AcDbFullSubentPath &subPath) { if (subType != AcDb::kNullSubentType) { // Make a subent path for a face or an edge using the // picked subentity (retrieved from the GS markers) subPath = subentIds[0]; subPath.objectIds() = objIdList; } else { // Make a subent path for a brep object (object ID array // with null subentity ID) subPath = kNullSubent; subPath.objectIds() = objIdList; } return; } Acad::ErrorStatus makeSubentPath(const AcDbObject *pObj, const AcDbObjectIdArray &objIdList, const AcDb::SubentType &subType, const short &marker, const AcGePoint3d &pickpnt, AcDbFullSubentPath &subPath) { Acad::ErrorStatus acadReturnValue = Acad::eOk; AcGeMatrix3d xform(AcGeMatrix3d::kIdentity); int numIds = 0L; AcDbFullSubentPath* subentIds = NULL; // Check to see if entity is a supported solid, surface, region or body AcDb3dSolid* pSolid(NULL); AcDbSurface* pSurface(NULL); AcDbRegion* pRegion(NULL); AcDbBody* pBody(NULL); AecDbBDPipeBase *pSH(NULL); if ((pSolid = AcDb3dSolid::cast(pObj)) != NULL) { if (subType != AcDb::kNullSubentType) acadReturnValue = pSolid->getSubentPathsAtGsMarker( subType, marker, pickpnt, xform, numIds, subentIds); if (subentIds != NULL) objIds2SubPath(objIdList, subType, subentIds, subPath); } else if ((pSurface = AcDbSurface::cast(pObj)) != NULL) { if (subType != AcDb::kNullSubentType) acadReturnValue = pSurface->getSubentPathsAtGsMarker( subType, marker, pickpnt, xform, numIds, subentIds); if (subentIds != NULL) objIds2SubPath(objIdList, subType, subentIds, subPath); } else if ((pRegion = AcDbRegion::cast(pObj)) != NULL) { if (subType != AcDb::kNullSubentType) acadReturnValue = pRegion->getSubentPathsAtGsMarker( subType, marker, pickpnt, xform, numIds, subentIds); if (subentIds != NULL) objIds2SubPath(objIdList, subType, subentIds, subPath); } else if ((pBody = AcDbBody::cast(pObj)) != NULL) { if (subType != AcDb::kNullSubentType) acadReturnValue = pBody->getSubentPathsAtGsMarker( subType, marker, pickpnt, xform, numIds, subentIds); if (subentIds != NULL) objIds2SubPath(objIdList, subType, subentIds, subPath); } else if ((pSH = AecDbBDPipeBase::cast(pObj)) != NULL) { if (subType != AcDb::kNullSubentType) acadReturnValue = pSH->getSubentPathsAtGsMarker(subType, marker, pickpnt, xform, numIds, subentIds); if (subentIds != NULL) objIds2SubPath(objIdList, subType, subentIds, subPath); } else { acutPrintf(ACRX_T("\n Selected object not a brep object\n")); return Acad::eWrongObjectType; } if (subentIds == NULL) acadReturnValue = Acad::ePointNotOnEntity; if (acadReturnValue != Acad::eOk) { acutPrintf(ACRX_T("\n getSubentPathsAtGsMarker failed\n")); errorReport((AcBr::ErrorStatus)acadReturnValue); return acadReturnValue; } return acadReturnValue; } Acad::ErrorStatus extractSolidFromBlock(ads_name ename, const AcDb::SubentType &subType, const short &marker, const AcGePoint3d &pickpnt, AcDbFullSubentPath &subPath) { Acad::ErrorStatus acadReturnValue = Acad::eOk; struct resbuf* insertStack; ads_matrix adsMatrix; int errStat = RTERROR; errStat = acedNEntSelP(NULL, ename, asDblArray(pickpnt), Adesk::kTrue, adsMatrix, &insertStack); if (errStat != RTNORM) { acutPrintf(ACRX_T("\n %d nentselp failed\n"), errStat); return acadReturnValue; } // ename should be the solid AcDbObjectId objId; acadReturnValue = acdbGetObjectId(objId, ename); if (acadReturnValue != Acad::eOk) { acutPrintf(ACRX_T("\n acdbGetObjectId failed\n")); errorReport((AcBr::ErrorStatus)acadReturnValue); return acadReturnValue; } // Use an existing transaction if there is one; // else open a new one Adesk::Boolean ownTransaction = Adesk::kFalse; acadReturnValue = dbOpenTransaction(ownTransaction); if (acadReturnValue != Acad::eOk) { acutPrintf(ACRX_T("\n Error in dbOpenTransaction:")); errorReport((AcBr::ErrorStatus)acadReturnValue); return acadReturnValue; } // Open the object for read-only AcDbObject* pObj = NULL; acadReturnValue = actrTransactionManager->getObject( pObj, objId, AcDb::kForRead); if (acadReturnValue != Acad::eOk) { dbAbortTransaction(ownTransaction); acutPrintf(ACRX_T("\n Error in getPath:")); errorReport((AcBr::ErrorStatus)acadReturnValue); return acadReturnValue; } int count = 0; AcDbObjectId* idArray = new AcDbObjectId[100]; idArray[count++] = objId; while (insertStack != NULL) { ename[0] = insertStack->resval.rlname[0]; ename[1] = insertStack->resval.rlname[1]; acadReturnValue = acdbGetObjectId(objId, ename); if (acadReturnValue != Acad::eOk) { acutPrintf(ACRX_T("\n acdbGetObjectId failed\n")); errorReport((AcBr::ErrorStatus)acadReturnValue); dbCloseTransaction(ownTransaction); return acadReturnValue; } idArray[count++] = objId; insertStack = insertStack->rbnext; } // Invert the list AcDbObjectIdArray objIdList; for (int j=(count-1); j>=0; j--) objIdList.append(idArray[j]); acadReturnValue = makeSubentPath(pObj, objIdList, subType, marker, pickpnt, subPath); if (acadReturnValue != Acad::eOk) { acutPrintf(ACRX_T("\n makeSubentPath failed\n")); dbCloseTransaction(ownTransaction); return acadReturnValue; } // Close the transaction dbCloseTransaction(ownTransaction); return acadReturnValue; } Acad::ErrorStatus selectEntity(const AcDb::SubentType &subType, AcDbFullSubentPath &subPath, const AcGePoint3d &pickPnt) { Acad::ErrorStatus acadReturnValue = Acad::eOk; int errStat = RTERROR; ads_name sset; //AcGePoint3d pickPnt; struct resbuf org_osnap; acedGetVar(ACRX_T("OSMODE"), &org_osnap); struct resbuf new_osnap = org_osnap; new_osnap.resval.rint = 0; acedSetVar(ACRX_T("OSMODE"), &new_osnap); //while ((errStat != RTNORM) && (errStat != RTCAN) && (errStat != RTREJ) && (errStat != RTNONE)) //{ // ads_name ent_name; // switch (subType) // { // case AcDb::kNullSubentType: // errStat = acedEntSel(ACRX_T("\n Pick a solid\n"), ent_name, asDblArray(pickPnt)); // break; // case AcDb::kFaceSubentType: // errStat = acedEntSel(ACRX_T("\n 请拾取一个面:\n"), ent_name, asDblArray(pickPnt)); // break; // case AcDb::kEdgeSubentType: // errStat = acedEntSel(ACRX_T("\n Pick an edge\n"), ent_name, asDblArray(pickPnt)); // break; // default: // acutPrintf(ACRX_T("\n getPath: unsupported subentity type: %d\n"), subType); // return Acad::eInvalidInput; // } // if (errStat == RTERROR) // { // struct resbuf buf_errno; // acedGetVar(ACRX_T("ERRNO"), &buf_errno); // if (buf_errno.resval.rint == OL_ENTSELNULL) errStat = RTNONE; // } //} //if (errStat == RTNORM) //{ errStat = acedSSGet(NULL, asDblArray(pickPnt), NULL, NULL, sset); //} acedSetVar(ACRX_T("OSMODE"), &org_osnap); if (errStat != RTNORM) return Acad::eAmbiguousInput; // Get the entity name struct resbuf* rb; errStat = acedSSNameX(&rb, sset, 0L); if (errStat != RTNORM) { acedSSFree(sset); return Acad::eAmbiguousInput; } // Free the selection set acedSSFree(sset); // The selected entity is the final entry in the resbuf int i; struct resbuf* pTemp; for (i = 1, pTemp = rb; i < 3; i++, pTemp = pTemp->rbnext) ; ads_name ename; ads_name_set(pTemp->resval.rlname, ename); // Get the GsMarker pTemp = pTemp->rbnext; short marker = pTemp->resval.rint; // Free the rb resbuf entity acutRelRb(rb); // Get the object ID of the selected entity AcDbObjectId objId; acadReturnValue = acdbGetObjectId(objId, ename); if (acadReturnValue != Acad::eOk) { acutPrintf(ACRX_T("\n acdbGetObjectId failed\n")); return acadReturnValue; } // Use an existing transaction if there is one; // else open a new one Adesk::Boolean ownTransaction = Adesk::kFalse; acadReturnValue = dbOpenTransaction(ownTransaction); if (acadReturnValue != Acad::eOk) { acutPrintf(ACRX_T("\n Error in dbOpenTransaction:")); errorReport((AcBr::ErrorStatus)acadReturnValue); return acadReturnValue; } // Open the object for read-only AcDbObject* pObj = NULL; acadReturnValue = actrTransactionManager->getObject( pObj, objId, AcDb::kForRead); if (acadReturnValue != Acad::eOk) { dbAbortTransaction(ownTransaction); acutPrintf(ACRX_T("\n Error in getPath:")); errorReport((AcBr::ErrorStatus)acadReturnValue); return acadReturnValue; } if (AcDbBlockReference::cast(pObj) != NULL) { acadReturnValue = extractSolidFromBlock(ename, subType, marker, pickPnt, subPath); if (acadReturnValue != Acad::eOk) { dbCloseTransaction(ownTransaction); acutPrintf(ACRX_T("\n extractSolidFromBlock failed\n")); return acadReturnValue; } } else { AcDbObjectIdArray objIdList; objIdList.append(objId); acadReturnValue = makeSubentPath(pObj, objIdList, subType, marker, pickPnt, subPath); if (acadReturnValue != Acad::eOk) { dbCloseTransaction(ownTransaction); acutPrintf(ACRX_T("\n makeSubentPath failed\n")); return acadReturnValue; } } // Close the transaction dbCloseTransaction(ownTransaction); return acadReturnValue; } AcBr::ErrorStatus selectEntityByType(AcBrEntity*& pEnt , const AcDb::SubentType &subType , const AcBr::ValidationLevel &vlevel , const AcGePoint3d &pickPnt ) { Acad::ErrorStatus acadReturnValue = Acad::eOk; AcBr::ErrorStatus returnValue = AcBr::eOk; // Query the subentity by AutoCAD pick and get the subentity path AcDbFullSubentPath subPath(kNullSubent); acadReturnValue = selectEntity(subType, subPath, pickPnt); if (acadReturnValue != Acad::eOk) { acutPrintf(ACRX_T("\n Error in selectEntity: %d"), acadReturnValue); return (AcBr::ErrorStatus)acadReturnValue; } // Call the appropriate subentity constructor switch (subType) { case AcDb::kNullSubentType: pEnt = new AcBrBrep(); break; case AcDb::kFaceSubentType: pEnt = new AcBrFace(); break; case AcDb::kEdgeSubentType: pEnt = new AcBrEdge(); break; default: acutPrintf(ACRX_T("\n selectEntityByType: unsupported subentity type: %d\n"), subType); returnValue = (AcBr::ErrorStatus)Acad::eWrongSubentityType; return returnValue; } if (pEnt == NULL) { acutPrintf(ACRX_T("\n selectEntityByType: unable to allocate memory\n")); returnValue = (AcBr::ErrorStatus)Acad::eOutOfMemory; return returnValue; } returnValue = pEnt->set(subPath); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrEntity::set:")); errorReport(returnValue); return returnValue; } returnValue = pEnt->setValidationLevel(vlevel); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrEntity::setValidationLevel:")); errorReport(returnValue); return returnValue; } return returnValue; } AcBr::ErrorStatus getNativeSurface(const AcBrFace& faceEntity, AcGeSurface *&surfaceGeometry, AcGeSurface *&nativeGeometry) { AcBr::ErrorStatus returnValue = faceEntity.getSurface(surfaceGeometry); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrFace::getSurface:")); errorReport(returnValue); return returnValue; } if (surfaceGeometry == NULL) { acutPrintf(ACRX_T("\n getNativeSurface: external bounded surface is undefined\n")); returnValue = AcBr::eMissingGeometry; return returnValue; } if (surfaceGeometry->type() != kExternalBoundedSurface) { acutPrintf(ACRX_T("\n getNativeSurface: surface is not an external bounded surface\n")); returnValue = AcBr::eMissingGeometry; return returnValue; } AcGeExternalSurface baseGeometry; ((AcGeExternalBoundedSurface*)surfaceGeometry)->getBaseSurface(baseGeometry); if (!baseGeometry.isDefined()) { acutPrintf(ACRX_T("\n getNativeSurface: external surface is undefined\n")); returnValue = AcBr::eMissingGeometry; return returnValue; } if (!baseGeometry.isNativeSurface(nativeGeometry) || (nativeGeometry == NULL)) { acutPrintf(ACRX_T("\n getNativeSurface: native surface is undefined\n")); returnValue = AcBr::eMissingGeometry; return returnValue; } return returnValue; } AcBr::ErrorStatus getNativeCurve(const AcBrEdge& edgeEntity, AcGeCurve3d*& curveGeometry, AcGeCurve3d*& nativeGeometry) { AcBr::ErrorStatus returnValue = edgeEntity.getCurve(curveGeometry); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrEdge::getCurve:")); errorReport(returnValue); return returnValue; } if (curveGeometry == NULL) { acutPrintf(ACRX_T("\n getNativeCurve: external 3d curve is undefined\n")); returnValue = AcBr::eMissingGeometry; return returnValue; } if (curveGeometry->type() != kExternalCurve3d) { acutPrintf(ACRX_T("\n getNativeCurve: curve is not an external 3d curve\n")); returnValue = AcBr::eMissingGeometry; return returnValue; } if (!((AcGeExternalCurve3d*)curveGeometry)->isDefined()) { acutPrintf(ACRX_T("\n getNativeCurve: external 3d curve is undefined\n")); returnValue = AcBr::eMissingGeometry; return returnValue; } if (!((AcGeExternalCurve3d*)curveGeometry)->isNativeCurve(nativeGeometry) || (nativeGeometry == NULL)) { acutPrintf(ACRX_T("\n getNativeCurve: native 3d curve is undefined\n")); returnValue = AcBr::eMissingGeometry; return returnValue; } return returnValue; } AcBr::ErrorStatus edgeDump(const AcBrEdge& edgeEntity, AcGeCurve3d *&pCurve, AcGe::EntityId &type) { AcBr::ErrorStatus returnValue = AcBr::eOk; if (edgeEntity.isA() == NULL) { acutPrintf(ACRX_T("\n edgeDump: AcBrEntity::isA() failed\n")); return returnValue; } if (!edgeEntity.isKindOf(AcBrEdge::desc())) { acutPrintf(ACRX_T("\n edgeDump: AcBrEntity::isKindOf() failed\n")); return returnValue; } AcBrEntity* entClass = (AcBrEntity*)&edgeEntity; AcBrFace* pFace = AcBrFace::cast(entClass); if (pFace != NULL) { acutPrintf(ACRX_T("\n edgeDump: AcBrEntity::cast() failed\n")); return (AcBr::ErrorStatus)Acad::eNotThatKindOfClass; } // validate the brep "owner" of the edge AcBrBrep brepOwner; returnValue = edgeEntity.getBrep(brepOwner); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrEdge::getBrep:")); errorReport(returnValue); return returnValue; } returnValue = edgeEntity.getCurveType(type); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrEdge::getCurveType:")); errorReport(returnValue); return returnValue; } AcGeCurve3d* curveGeometry = NULL; returnValue = getNativeCurve(edgeEntity, curveGeometry, pCurve); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in getNativeCurve:")); errorReport(returnValue); delete curveGeometry; delete pCurve; return returnValue; } delete curveGeometry; Adesk::Boolean oriented; returnValue = edgeEntity.getOrientToCurve(oriented); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrEdge::getOrientToCurve:")); errorReport(returnValue); return returnValue; } return returnValue; } AcDbCurve* geCurve2dbCurve(AcGeCurve3d *pGe, const AcGe::EntityId &type) { switch (type) { case(kLine3d): { AcGeLine3d* lineGeometry = (AcGeLine3d*)pGe; AcGePoint3d pt1, pt2; if (lineGeometry->hasStartPoint(pt1) && lineGeometry->hasEndPoint(pt2)) return new AcDbLine(pt1, pt2); return NULL; } case(kRay3d): { AcGeRay3d* rayGeometry = (AcGeRay3d*)pGe; AcGePoint3d pt = rayGeometry->pointOnLine(); AcGeVector3d dir = rayGeometry->direction(); AcGePoint3d pt1; if (rayGeometry->hasStartPoint(pt1)) { AcDbRay *pRay = new AcDbRay(); pRay->setBasePoint(pt1); pRay->setUnitDir(dir); return pRay; } return NULL; } case(kLineSeg3d): { AcGeLineSeg3d* segGeometry = (AcGeLineSeg3d*)pGe; AcGePoint3d pt1, pt2; if (segGeometry->hasStartPoint(pt1) && segGeometry->hasEndPoint(pt2)) return new AcDbLine(pt1, pt2); return NULL; } case(kEllipArc3d): { AcGeEllipArc3d* ellipGeometry = (AcGeEllipArc3d*)pGe; AcGePoint3d centre = ellipGeometry->center(); AcDbEllipse *p = new AcDbEllipse(ellipGeometry->center() , ellipGeometry->normal() , ellipGeometry->majorAxis() * ellipGeometry->majorRadius() , ellipGeometry->minorRadius() / ellipGeometry->majorRadius() , ellipGeometry->startAng() , ellipGeometry->endAng()); return p; } case(kCircArc3d): { AcGeCircArc3d* circGeometry = (AcGeCircArc3d*)pGe; AcGePoint3d centre = circGeometry->center(); AcGePoint3d start = circGeometry->startPoint(); AcGePoint3d end = circGeometry->endPoint(); double sa = circGeometry->startAng(); double ea = circGeometry->endAng(); if (sa < .0001 && ea - 2 * PI < .0001) // circle { return new AcDbCircle(circGeometry->center() , circGeometry->normal() , circGeometry->radius()); } else // arc { return new AcDbArc(circGeometry->center() , circGeometry->normal() , circGeometry->radius() , circGeometry->startAng() , circGeometry->endAng() ); } break; } case(kNurbCurve3d): { AcGeNurbCurve3d* nurbGeometry = (AcGeNurbCurve3d*)pGe; int count = nurbGeometry->numControlPoints(); AcGePoint3dArray ctrlPts; for (int i = 0; i < count; ++i) ctrlPts.append(nurbGeometry->controlPointAt(i)); count = nurbGeometry->numKnots(); AcGeDoubleArray Knots; for (int i = 0; i < count; ++i) Knots.append(nurbGeometry->knotAt(i)); count = nurbGeometry->numWeights(); AcGeDoubleArray Weights; for (int i = 0; i < count; ++i) Weights.append(nurbGeometry->weightAt(i)); return new AcDbSpline(nurbGeometry->degree() , nurbGeometry->isRational() , nurbGeometry->isClosed() , false , ctrlPts , Knots , Weights); } default: acutPrintf(ACRX_T("\nCurve Type: Unexpected Non Curve\n")); return NULL; } return NULL; } AcBr::ErrorStatus faceDump(const AcBrFace& faceEntity , AcGe::EntityId &geType , AcGeSurface *&nativeGeometry , int &orient ) { AcBr::ErrorStatus returnValue = AcBr::eOk; if (faceEntity.isA() == NULL) { acutPrintf(ACRX_T("\n faceDump: AcBrEntity::isA() failed\n")); return returnValue; } if (!faceEntity.isKindOf(AcBrFace::desc())) { acutPrintf(ACRX_T("\n faceDump: AcBrEntity::isKindOf() failed\n")); return returnValue; } AcBrEntity* entClass = (AcBrEntity*)&faceEntity; AcBrEdge* pEdge = AcBrEdge::cast(entClass); if (pEdge != NULL) { acutPrintf(ACRX_T("\n faceDump: AcBrEntity::cast() failed\n")); return (AcBr::ErrorStatus)Acad::eNotThatKindOfClass; } AcGe::EntityId entId; returnValue = faceEntity.getSurfaceType(entId); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrFace::getSurfaceType:")); errorReport(returnValue); return returnValue; } geType = entId; AcGeSurface* surfaceGeometry = NULL; returnValue = getNativeSurface(faceEntity, surfaceGeometry, nativeGeometry); if ((returnValue != AcBr::eOk) && (returnValue != (AcBr::ErrorStatus)Acad::eInvalidInput)) { acutPrintf(ACRX_T("\n Error in getNativeSurface:")); errorReport(returnValue); delete surfaceGeometry; delete nativeGeometry; return returnValue; } delete surfaceGeometry; Adesk::Boolean oriented; returnValue = faceEntity.getOrientToSurface(oriented); if (returnValue != AcBr::eOk) { acutPrintf(ACRX_T("\n Error in AcBrFace::getOrientToSurface:")); errorReport(returnValue); return returnValue; } oriented ? acutPrintf(ACRX_T("\nSurface Orientation is Positive\n")) : acutPrintf(ACRX_T("\nSurface Orientation is Negative\n")); orient = oriented ? 1 : -1; return returnValue; } AcBrFace* selectBrFace(const AcGePoint3d &pickPnt) { AcBrEntity *pBrEnt(NULL); if (selectEntityByType(pBrEnt, AcDb::kFaceSubentType, AcBr::kFullValidation, pickPnt) != AcBr::eOk) return NULL; return (AcBrFace*)pBrEnt; } AcBrEdge* selectBrEdge(const AcGePoint3d &pickPnt) { AcBrEntity *pBrEnt(NULL); if (selectEntityByType(pBrEnt, AcDb::kEdgeSubentType, AcBr::kFullValidation, pickPnt) != AcBr::eOk) return NULL; return (AcBrEdge*)pBrEnt; } bool getPlaneByBrFace(const AcBrFace *pFace, AcGePlane &plan) { if (!pFace) return false; AcGeSurface *pSurface(NULL); AcGe::EntityId geType; int orient; AcBr::ErrorStatus es = faceDump(*pFace, geType, pSurface, orient); if (es != AcBr::eOk || !pSurface) { DELETE_PTR(pSurface); return false; } bool bRel(true); if (pSurface->isKindOf(AcGe::kPlane)) { plan = (*(AcGePlane*)pSurface); } else if (pSurface->isKindOf(AcGe::kSphere)) { AcGeSphere *sphereGeometry = (AcGeSphere*)pSurface; plan.set(sphereGeometry->center(), sphereGeometry->northAxis()); } else if (pSurface->isKindOf(AcGe::kTorus)) { AcGeTorus *torusGeometry = (AcGeTorus*)pSurface; plan.set(torusGeometry->center(), torusGeometry->axisOfSymmetry()); } else if (pSurface->isKindOf(AcGe::kCylinder)) { AcGeCylinder *cylinderGeometry = (AcGeCylinder*)pSurface; AcGeVector3d refAxis = cylinderGeometry->refAxis(); plan.set(cylinderGeometry->origin() + refAxis * cylinderGeometry->radius(), refAxis); } else if (pSurface->isKindOf(AcGe::kCone)) { AcGeCone *coneGeometry = (AcGeCone*)pSurface; AcGeVector3d refAxis = coneGeometry->refAxis(); plan.set(coneGeometry->baseCenter() + refAxis * coneGeometry->baseRadius(), refAxis); } //else if (pSurface->isKindOf(AcGe::kNurbSurface)) //{ // AcGeNurbSurface *nurbGeometry = (AcGeNurbSurface*)pSurface; // acutPrintf(_T("\n暂不支持此类曲面!")); //} else { acutPrintf(_T("\n暂不支持此类曲面!")); bRel = false; } DELETE_PTR(pSurface); if (bRel) { if (orient < 0) plan.reverseNormal(); } return bRel; } void setColorForSolid(AcDbObjectId solidId) { AcCmColor specialColor; AcDb3dSolid* pSolid; if (Acad::eOk == acdbOpenObject(pSolid, solidId, AcDb::kForRead)) { AcDbFullSubentPath path(solidId, AcDbSubentId()); AcBrBrep brep; AcBr::ErrorStatus bs = brep.setSubentPath(path); if (bs != AcBr::eOk) return; //Initialize the BrepFace traverser AcBrBrepFaceTraverser bft; bs = bft.setBrep(brep); if (bs != AcBr::eOk) return; AcArray arrSubentId; // Traverse all faces for (;!bft.done();bft.next()) { AcBrFace face; bs = bft.getFace(face); if (bs != Acad::eOk) { acutPrintf(L"\ngetFace failed"); break; } AcDbFullSubentPath Path(kNullSubent); AcDbSubentId subentId; AcBr::ErrorStatus bss = face.getSubentPath(Path); subentId = Path.subentId(); arrSubentId.append(subentId); } pSolid->upgradeOpen(); for (int i = 0; i < arrSubentId.length(); i++) { specialColor.setColorIndex(i); pSolid->setSubentColor(arrSubentId[i],specialColor); } pSolid->downgradeOpen(); } pSolid->close(); } void getProfileByFace(AcBrFace *pFace, AcDbVoidPtrArray &curves) { if (!pFace) return; AcBrFaceLoopTraverser faLoTrav; AcGe::EntityId type; for (faLoTrav.setFace(*pFace); !faLoTrav.done(); faLoTrav.next()) { AcBrLoopEdgeTraverser loEdTrav; if (loEdTrav.setLoop(faLoTrav) == AcBr::eOk) { for( ; !loEdTrav.done(); loEdTrav.next()) { AcBrEdge edge; loEdTrav.getEdge(edge); AcGeCurve3d *pGe(NULL); if (AcBr::eOk == edgeDump(edge, pGe, type) && pGe) { AcDbCurve *pCrv = geCurve2dbCurve(pGe, type); if (pCrv) curves.append(pCrv); DELETE_PTR(pGe); } } } } } void getProfileByFace2(AcBrFace *pFace, AcDbVoidPtrArray &curvesOut, AcDbVoidPtrArray&curvesIn) { if (!pFace) return; AcBrFaceLoopTraverser faLoTrav; AcGe::EntityId type; for (faLoTrav.setFace(*pFace); !faLoTrav.done(); faLoTrav.next()) { AcBrLoopEdgeTraverser loEdTrav; if (loEdTrav.setLoop(faLoTrav) == AcBr::eOk) { for (; !loEdTrav.done(); loEdTrav.next()) { AcBrEdge edge; loEdTrav.getEdge(edge); AcBrLoop brLoop; loEdTrav.getLoop(brLoop); AcBr::LoopType ltype = AcBr::kUnclassified; brLoop.getType(ltype); AcGeCurve3d *pGe(NULL); if (AcBr::eOk == edgeDump(edge, pGe, type) && pGe) { AcDbCurve *pCrv = geCurve2dbCurve(pGe, type); if (pCrv) { (ltype == AcBr::kInterior) ? curvesIn.append(pCrv) : curvesOut.append(pCrv); } DELETE_PTR(pGe); } } } } } void impget3DSolidToPolyMesh() { ads_name en; ads_point p; if (acedEntSel(_T("\nSelect 3DSolid:"), en, p) != RTNORM) return; AcDbObjectId eid; if (acdbGetObjectId(eid, en) != Acad::eOk) return; AcDbObjectPointer p3DSolid(eid, AcDb::kForRead); if (p3DSolid.openStatus() == Acad::eWrongObjectType) { acutPrintf(_T("\nEnt is not a 3dsolid!")); return; } AcDbExtents ext; p3DSolid->getGeomExtents(ext); double length = ext.minPoint().distanceTo(ext.maxPoint()); AcBrBrep brp; AcBr::ErrorStatus ebr; ebr = brp.set(*p3DSolid); if (ebr != AcBr::eOk) { acutPrintf(_T("\nerror br.set(*p3DSolid) = %d"), ebr); return; } AcBrMesh2dControl mc; // mc.setMaxNodeSpacing( length / 100.0); // mc.setMaxSubdivisions(100000); mc.setDistTol(length / 100.0); mc.setElementShape(AcBr::kAllTriangles); AcBrMesh2dFilter mf; const AcBrEntity *meshEnt = (AcBrEntity *)&brp; mf.insert(make_pair(meshEnt, mc)); AcBrMesh2d brepMesh; if ((ebr = brepMesh.generate(mf)) != AcBr::eOk) { acutPrintf(_T("\nerror AcBrMesh2d::generate %d"), ebr); return; } AcDbObjectPointer pMesh; pMesh.create(); pMesh->setDatabaseDefaults(); pMesh->setColorIndex(2); AcDbBlockTableRecordPointer pBtr(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite); if (pBtr.openStatus() != Acad::eOk) return; pBtr->appendAcDbEntity(pMesh); int v0 = 0, v1 = 0, v2 = 0, v3 = 0; int iter = 0; AcGePoint3dArray vertexLookup; vertexLookup.setPhysicalLength(10000); vertexLookup.append(AcGePoint3d::kOrigin); AcBrMesh2dElement2dTraverser meshElemTrav; for (ebr = meshElemTrav.setMesh(brepMesh); !meshElemTrav.done(); ebr = meshElemTrav.next()) { if (ebr != AcBr::eOk) return; AcBrElement2d e; ebr = meshElemTrav.getElement(e); AcBrElement2dNodeTraverser elemNodeTrav; for (ebr = elemNodeTrav.setElement(e); !elemNodeTrav.done(); elemNodeTrav.next()) { AcBrNode brn; ebr = elemNodeTrav.getNode(brn); AcGePoint3d p; brn.getPoint(p); if (!vertexLookup.contains(p)) { AcDbObjectPointer pMeshVert; pMeshVert.create(); pMeshVert->setPosition(p); pMesh->appendVertex(pMeshVert); vertexLookup.append(p); } } } for (ebr = meshElemTrav.setMesh(brepMesh); !meshElemTrav.done(); ebr = meshElemTrav.next()) { if (ebr != AcBr::eOk) return; AcBrElement2d e; ebr = meshElemTrav.getElement(e); AcBrElement2dNodeTraverser elemNodeTrav; AcGePoint3dArray pts; for (ebr = elemNodeTrav.setElement(e); !elemNodeTrav.done(); ebr = elemNodeTrav.next()) { if (ebr != AcBr::eOk) return; AcBrNode brn; ebr = elemNodeTrav.getNode(brn); AcGePoint3d p; brn.getPoint(p); pts.append(p); } v0 = v1 = v2 = v3 = 0; vertexLookup.find(pts[0], v0); vertexLookup.find(pts[1], v1); vertexLookup.find(pts[2], v2); if (pts.length() == 4) { vertexLookup.find(pts[3], v3); } AcDbFaceRecord *pFaceRecord = new AcDbFaceRecord(v0, v1, v2, v3); pMesh->appendFaceRecord(pFaceRecord); pFaceRecord->close(); } } bool impget3DSolidToPolyMesh(AcDb3dSolid* p3DSolid, CString& sVertices, CString& sIndices) { CString sPt,sInd; AcDbExtents ext; p3DSolid->getGeomExtents(ext); double length = ext.minPoint().distanceTo(ext.maxPoint()); AcBrBrep brp; AcBr::ErrorStatus ebr; ebr = brp.set(*p3DSolid); if (ebr != AcBr::eOk) { acutPrintf(_T("\nerror br.set(*p3DSolid) = %d"), ebr); return false; } AcBrMesh2dControl mc; // mc.setMaxNodeSpacing( length / 100.0); // mc.setMaxSubdivisions(100000); mc.setDistTol(length / 100.0); mc.setElementShape(AcBr::kAllTriangles); AcBrMesh2dFilter mf; const AcBrEntity *meshEnt = (AcBrEntity *)&brp; mf.insert(make_pair(meshEnt, mc)); AcBrMesh2d brepMesh; if ((ebr = brepMesh.generate(mf)) != AcBr::eOk) { acutPrintf(_T("\nerror AcBrMesh2d::generate %d"), ebr); return false; } //AcDbObjectPointer pMesh; //pMesh.create(); //pMesh->setDatabaseDefaults(); //pMesh->setColorIndex(2); //AcDbBlockTableRecordPointer pBtr(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite); //if (pBtr.openStatus() != Acad::eOk) // return; //pBtr->appendAcDbEntity(pMesh); int v0 = 0, v1 = 0, v2 = 0, v3 = 0; int iter = 0; AcGePoint3dArray vertexLookup; vertexLookup.setPhysicalLength(10000); vertexLookup.append(AcGePoint3d::kOrigin); AcBrMesh2dElement2dTraverser meshElemTrav; for (ebr = meshElemTrav.setMesh(brepMesh); !meshElemTrav.done(); ebr = meshElemTrav.next()) { if (ebr != AcBr::eOk) return false; AcBrElement2d e; ebr = meshElemTrav.getElement(e); AcBrElement2dNodeTraverser elemNodeTrav; for (ebr = elemNodeTrav.setElement(e); !elemNodeTrav.done(); elemNodeTrav.next()) { AcBrNode brn; ebr = elemNodeTrav.getNode(brn); AcGePoint3d p; brn.getPoint(p); if (!vertexLookup.contains(p)) { AcDbObjectPointer pMeshVert; pMeshVert.create(); pMeshVert->setPosition(p); //pMesh->appendVertex(pMeshVert); sPt.Format(_T("%.3f,%.3f,%.3f,"),p.x,p.y,p.z); sVertices += sPt; vertexLookup.append(p); } } } sVertices.TrimRight(_T(',')); for (ebr = meshElemTrav.setMesh(brepMesh); !meshElemTrav.done(); ebr = meshElemTrav.next()) { if (ebr != AcBr::eOk) return false; AcBrElement2d e; ebr = meshElemTrav.getElement(e); AcBrElement2dNodeTraverser elemNodeTrav; AcGePoint3dArray pts; for (ebr = elemNodeTrav.setElement(e); !elemNodeTrav.done(); ebr = elemNodeTrav.next()) { if (ebr != AcBr::eOk) return false; AcBrNode brn; ebr = elemNodeTrav.getNode(brn); AcGePoint3d p; brn.getPoint(p); pts.append(p); } v0 = v1 = v2 = v3 = 0; vertexLookup.find(pts[0], v0); vertexLookup.find(pts[1], v1); vertexLookup.find(pts[2], v2); if (pts.length() == 4) { vertexLookup.find(pts[3], v3); sInd.Format(_T("%d,%d,%d,"), v0, v1, v2); sIndices += sInd; sInd.Format(_T("%d,%d,%d,"), v0, v2, v3); sIndices += sInd; } else { sInd.Format(_T("%d,%d,%d,"),v0,v1,v2); sIndices += sInd; } //AcDbFaceRecord *pFaceRecord = new AcDbFaceRecord(v0, v1, v2, v3); //pMesh->appendFaceRecord(pFaceRecord); //pFaceRecord->close(); } sIndices.TrimRight(_T(',')); return true; } } void BrepOper::setUCS(AcGePlane &plan, bool bPlan) { AcGePoint3d pt; AcGeVector3d vtNormal(plan.normal()), vt1, vt2; plan.getCoordSystem(pt, vt1, vt2); AcGeMatrix3d mat; AcGeVector3d vt(vt1.crossProduct(vt2)); if (vt.negate().isCodirectionalTo(vtNormal)) mat.setCoordSystem(pt, vt2, vt1, vtNormal); else mat.setCoordSystem(pt, vt1, vt2, vtNormal); acedSetCurrentUCS(mat); if (bPlan) SHacedCommand(RTSTR, _T("PLAN"), RTSTR, _T(""), RTNONE); } bool BrepOper::setUCSByFace(AcBrFace *pFace, bool bPlan) { AcGePlane plane; if (getPlaneByBrepFace(pFace, plane)) { BrepOper::setUCS(plane, bPlan); return true; } return false; } bool BrepOper::setUCSBySubentPath(AcDbFullSubentPath &path, bool bPlan) { if (path.subentId().type() != AcDb::kFaceSubentType) return false; AcBrFace face; if (face.set(path) != AcBr::eOk) return false; return setUCSByFace(&face, bPlan); } void BrepOper::getSubPathBySolid(AcDbObjectId & solidId, AcArray& subs, AcArray &plans) { AcDbFullSubentPath path(solidId, AcDbSubentId()); AcBrBrep brep; AcBr::ErrorStatus bs = brep.setSubentPath(path); if (bs != AcBr::eOk) return; AcBrBrepFaceTraverser bft; bs = bft.setBrep(brep); if (bs != AcBr::eOk) return; AcDbFullSubentPath Path(kNullSubent); AcGeSurface *pSu(NULL); for (;!bft.done();bft.next()) { AcBrFace face; bs = bft.getFace(face); if (bs != Acad::eOk) { acutPrintf(L"\ngetFace failed"); break; } AcGePlane plan; if (face.getSubentPath(Path) == AcBr::eOk && getPlaneByBrFace(&face, plan)) { subs.append(Path.subentId()); plans.append(plan); } } } AcDb3dSolid* BrepOper::get3DSolidBySH(AcDbObjectId &idSH) { AcDbVoidPtrArray ar3d; OPENOBJ_BEGIN(idSH, AcDb::kForRead, AecDbEntityBase, pEw) if (pEw) pEw->GetDraw3dables(ar3d); OPENOBJ_END() OPENOBJ_BEGIN(idSH, AcDb::kForRead, AecDbCurveBase, pEw) if (pEw) pEw->GetDraw3dables(ar3d); OPENOBJ_END() if (ar3d.isEmpty()) return NULL; std::vector solids; AcDb3dSolid *pSolid(NULL); for (int i = 0; i < ar3d.length(); ++i) { pSolid = AcDb3dSolid::cast((AcDbEntity*)ar3d[i]); if (pSolid) solids.push_back((AcDb3dSolid*)pSolid->clone()); } if (solids.empty()) return NULL; AcDb3dSolid *pSolidAll(solids[0]); for (size_t i = 1; i < solids.size(); ++i) { if (pSolidAll->booleanOper(AcDb::kBoolUnite, solids[i]) != Acad::eOk) DELETE_PTR(solids[i]); } return pSolidAll; } bool BrepOper::setUcsByPickFace(AcDbObjectId &idSH, const AcGePoint3d &pickPnt, AcDbVoidPtrArray *pAr) { AcDbFullSubentPathArray arPaths; AcDb3dSolid *pSolidAll = get3DSolidBySH(idSH); if (!pSolidAll) return false; AcDbObjectId idSolid; CoreTools::AddToModelSpace(pSolidAll, NULL, true, &idSolid); SHacedCommand(RTSTR, _T("regen"), RTNONE); OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AcDbEntity, pEw) if (pEw) pEw->setVisibility(AcDb::kInvisible); OPENOBJ_END() selectSubentPaths(_T("3DSOLID"), asDblArray(pickPnt), AcDb::kFaceSubentType, arPaths); bool bRel(false); if (!arPaths.isEmpty()) { bRel = setUCSBySubentPath(arPaths.first(), false); if (pAr && bRel) { AcBrFace face; if (face.set(arPaths.first()) == AcBr::eOk) getProfileByFace(&face, *pAr); } } OPENOBJ_BEGIN(idSolid, AcDb::kForWrite, AcDb3dSolid, pEnt) if (pEnt) pEnt->erase(); OPENOBJ_END() OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AcDbEntity, pEw) if (pEw) pEw->setVisibility(AcDb::kVisible); OPENOBJ_END() return bRel; } void BrepOper::copyEdgeByFace(AcDbObjectId &idSH, const AcGePoint3d &pickPnt, AcDbCurve *&pEdge) { AcDb3dSolid *pSolidAll = get3DSolidBySH(idSH); if (!pSolidAll) return; AcDbObjectId idSolid; CoreTools::AddToModelSpace(pSolidAll, NULL, true, &idSolid); SHacedCommand(RTSTR, _T("regen"), RTNONE); OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AecDbEwPipeBase, pEw) if (pEw) pEw->setVisibility(AcDb::kInvisible); OPENOBJ_END() AcDbFullSubentPathArray arPaths; selectSubentPaths(_T("3DSOLID"), asDblArray(pickPnt), AcDb::kEdgeSubentType, arPaths); if (!arPaths.isEmpty()) { AcDbFullSubentPath &path(arPaths.first()); AcBrEdge edge; if (edge.set(path) == AcBr::eOk) { AcGe::EntityId type; AcGeCurve3d *pGe(NULL); if (AcBr::eOk == edgeDump(edge, pGe, type) && pGe) { pEdge = geCurve2dbCurve(pGe, type); DELETE_PTR(pGe); } } } OPENOBJ_BEGIN(idSolid, AcDb::kForWrite, AcDb3dSolid, pEnt) if (pEnt) pEnt->erase(); OPENOBJ_END() OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AecDbEwPipeBase, pEw) if (pEw) pEw->setVisibility(AcDb::kVisible); OPENOBJ_END() } bool BrepOper::getPlaneByBrepFace(const AcBrFace *pFace, AcGePlane &plan) { AcGe::EntityId suType; AcBr::ErrorStatus es; if ((es = pFace->getSurfaceType(suType)) != AcBr::eOk) { acutPrintf(_T("\ngetSurfaceType err%d"), es); return false; } if (suType != AcGe::kPlane) { acutPrintf(_T("\n所选面必须是平面!")); return false; } Adesk::Boolean bOrient(false); if ((es = pFace->getOrientToSurface(bOrient)) != AcBr::eOk) { acutPrintf(_T("\ngetOrientToSurface err:%d"), es); return false; } AcGeSurface *pSurface(NULL), *pNative(NULL); if ((es = pFace->getSurface(pSurface)) != AcBr::eOk) { acutPrintf(_T("\ngetSurface err:%d"), es); return false; } if (pSurface->type() != kExternalBoundedSurface) { acutPrintf(_T("\nSurface is not kExternalBoundedSurface"), es); return false; } AcGeExternalBoundedSurface *pSur = (AcGeExternalBoundedSurface *)pSurface; AcGeExternalSurface baseGeometry; pSur->getBaseSurface(baseGeometry); if (!baseGeometry.isDefined()) { acutPrintf(_T("\nbaseGeometry is undefined!")); DELETE_PTR(pSurface); return false; } if (baseGeometry.isNativeSurface(pNative) && pNative) { plan = *(AcGePlane*)pNative; if (!bOrient) plan.reverseNormal(); DELETE_PTR(pNative); return true; } else { acutPrintf(_T("\nNative surface is undefined!")); } return false; } bool BrepOper::selectSubentPaths(LPCTSTR filter , ads_point adsPt , const AcDb::SubentType &subType , AcDbFullSubentPathArray &paths) { ads_name ss; AcArray subTypes; subTypes.append(subType); acedSSSetSubentTypes(subTypes); struct resbuf *pRb(NULL); if (filter) pRb = acutBuildList(RTDXF0, filter, 0); #ifndef ZWCAD int nRet = acedSSGet(_T("_:V:S"), adsPt, NULL, pRb, ss); #else CString str; if (subType == AcDb::kFaceSubentType) str = _T("\n中望用户请再选择一次面:"); else if (subType == AcDb::kEdgeSubentType) str = _T("\n中望用户请再选择一次边:"); LPCTSTR prompts[] = { str, _T("") }; int nRet = acedSSGet(_T("_:V:S:$"), prompts, NULL, pRb, ss); #endif if (pRb) acutRelRb(pRb); if (nRet != RTNORM) return false; Adesk::Int32 nEnts = 0, nSubs = 0; acedSSLength(ss, &nEnts); AcDbFullSubentPath path; for (int i = 0; i < nEnts; i++) { acedSSSubentLength(ss, i, &nSubs); for (int j = 0; j < nSubs; j++) { acedSSSubentName(ss, i, j, path); paths.append(path); } } acedSSFree(ss); return !paths.isEmpty(); } bool BrepOper::getProfileByPickFace(AcDbObjectId &idSH , const AcGePoint3d &pickPnt , AcDbVoidPtrArray &ptrs) { AcDbFullSubentPathArray arPaths; AcDb3dSolid *pSolidAll = get3DSolidBySH(idSH); if (!pSolidAll) return false; AcDbObjectId idSolid; CoreTools::AddToModelSpace(pSolidAll, NULL, true, &idSolid); SHacedCommand(RTSTR, _T("regen"), RTNONE); OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AcDbEntity, pEw) if (pEw) pEw->setVisibility(AcDb::kInvisible); OPENOBJ_END() selectSubentPaths(_T("3DSOLID"), asDblArray(pickPnt), AcDb::kFaceSubentType, arPaths); if (!arPaths.isEmpty()) { AcBrFace face; if (face.set(arPaths.first()) == AcBr::eOk) getProfileByFace(&face, ptrs); } OPENOBJ_BEGIN(idSolid, AcDb::kForWrite, AcDb3dSolid, pEnt) if (pEnt) pEnt->erase(); OPENOBJ_END() OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AcDbEntity, pEw) if (pEw) pEw->setVisibility(AcDb::kVisible); OPENOBJ_END() return !ptrs.isEmpty(); } bool BrepOper::getProfileByPickFace2(AcDbObjectId &idSH , const AcGePoint3d &pickPnt , AcDbVoidPtrArray &ptrsOut , AcDbVoidPtrArray &ptrsIn) { AcDbFullSubentPathArray arPaths; AcDb3dSolid *pSolidAll = get3DSolidBySH(idSH); if (!pSolidAll) return false; AcDbObjectId idSolid; CoreTools::AddToModelSpace(pSolidAll, NULL, true, &idSolid); SHacedCommand(RTSTR, _T("regen"), RTNONE); OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AcDbEntity, pEw) if (pEw) pEw->setVisibility(AcDb::kInvisible); OPENOBJ_END() selectSubentPaths(_T("3DSOLID"), asDblArray(pickPnt), AcDb::kFaceSubentType, arPaths); if (!arPaths.isEmpty()) { AcBrFace face; if (face.set(arPaths.first()) == AcBr::eOk) getProfileByFace2(&face, ptrsOut,ptrsIn); } OPENOBJ_BEGIN(idSolid, AcDb::kForWrite, AcDb3dSolid, pEnt) if (pEnt) pEnt->erase(); OPENOBJ_END() OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AcDbEntity, pEw) if (pEw) pEw->setVisibility(AcDb::kVisible); OPENOBJ_END() return !ptrsOut.isEmpty() || !ptrsIn.isEmpty(); } bool BrepOper::getProfileByPickFace3(AcDbObjectId &idSH , const AcGePoint3d &pickPnt , AcDbVoidPtrArray &ptrsOut , AcDbVoidPtrArray &ptrsIn , void*& pFaceSolid)// { AcDbFullSubentPathArray arPaths; AcDb3dSolid *pSolidAll = get3DSolidBySH(idSH); if (!pSolidAll) return false; AcDbObjectId idSolid; CoreTools::AddToModelSpace(pSolidAll, NULL, true, &idSolid); SHacedCommand(RTSTR, _T("regen"), RTNONE); OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AcDbEntity, pEw) if (pEw) pEw->setVisibility(AcDb::kInvisible); OPENOBJ_END() selectSubentPaths(_T("3DSOLID"), asDblArray(pickPnt), AcDb::kFaceSubentType, arPaths); if (!arPaths.isEmpty()) { AcBrFace face; if (face.set(arPaths.first()) == AcBr::eOk) getProfileByFace2(&face, ptrsOut, ptrsIn); AcDbEntity *pEntT = NULL; AcDbFullSubentPath& path = arPaths.first(); pSolidAll->copyFace(path.subentId(), pEntT); pFaceSolid = pEntT; } OPENOBJ_BEGIN(idSolid, AcDb::kForWrite, AcDb3dSolid, pEnt) if (pEnt) pEnt->erase(); OPENOBJ_END() OPENOBJ_BEGIN(idSH, AcDb::kForWrite, AcDbEntity, pEw) if (pEw) pEw->setVisibility(AcDb::kVisible); OPENOBJ_END() return !ptrsOut.isEmpty() || !ptrsIn.isEmpty(); } AcDbSubentId BrepOper::Acad2Zcad(const AcDbSubentId &idCad) { #ifdef ZWCAD AcDb::SubentType subType = idCad.type(); Adesk::GsMarker subIndex = idCad.index() + 1; return AcDbSubentId (subType, subIndex * 4 + subType); #else return idCad; #endif } namespace { void pickFaceForSolid() { #ifdef ZWCAD SHacedCommand(RTSTR, _T("_SHADEMODE"), RTSTR, _T("_G"), RTNONE); #else SHacedCommand(RTSTR, _T("_vscurrent"), RTSTR, _T("c"), RTNONE); #endif ads_name ent, ss; ads_point adsPt; LPCTSTR pszMsg[] = { _T("\n选择一个三维实体:"), _T("")}; struct resbuf *pRb = acutBuildList(RTDXF0, _T("3DSOLID"), 0); #ifdef ZWCAD int nRes = acedSSGet(_T("_:V:S:$"), pszMsg, NULL, pRb, ss); #else int nRes = acedSSGet(_T("_:S:$"), pszMsg, NULL, pRb, ss); #endif acutRelRb(pRb); if (nRes != RTNORM) return; nRes = acedSSNameX(&pRb, ss, 0L); acedSSFree(ss); if (nRes != RTNORM) return; struct resbuf *pTemp = pRb; pTemp = pTemp->rbnext; pTemp = pTemp->rbnext; ads_name_set(pTemp->resval.rlname, ent); pTemp = pTemp->rbnext; int gsMarker = pTemp->resval.rint; acutRelRb(pRb); acutPrintf(_T("\nGS:%d"), gsMarker); } void setColorForSolid() { ads_name ent, ss; ads_point adsPt; LPCTSTR pszMsg[] = { _T("\n选择一个3dPolyline:"), _T("") }; //struct resbuf *pRb = acutBuildList(RTDXF0, _T("3DSOLID"), 0); int nRes = acedEntSel(NULL, ent, adsPt); if (nRes != RTNORM) return; OPENOBJ_BEGIN(ent, AcDb::kForWrite, AcDbCurve, pPl); if (pPl) { AcDbCurve *pNew = (AcDbCurve*)pPl->clone(); AecDbEntityBase::CopyObject(*pPl, *pNew); AcGePoint3d ptStart(AcGePoint3d::kOrigin); Acad::ErrorStatus es = pNew->getStartPoint(ptStart); acutPrintf(_T("err:%d"), es); DELETE_PTR(pNew); } OPENOBJ_END(); } } void BrepOper::test() { //pickFaceForSolid(); setColorForSolid(); } void BrepOper::get3DSolidToPolyMesh() { impget3DSolidToPolyMesh(); } bool BrepOper::PolyhedronGeometry(AcDb3dSolid* p3d, CString& sVertices, CString& sIndices) { sVertices = _T(""); sIndices = _T(""); return impget3DSolidToPolyMesh(p3d, sVertices, sIndices); }