#include "stdafx.h" #include "AcGiViewDraw.h" #include "AecDbCamera.h" #include "dbgrip.h" #include "MFCDbDwgFiler.h" #include "CoreTools.h" #include "HlrCutOption.h" #include "aecdbewpipebase.h" #include "compare_double.h" #include "simpleproperty.h" #include "hlrcommands.h" IMP_XDATA_KEY(AecDbXCamera, _ptEye_); IMP_XDATA_KEY(AecDbXCamera, _vtEye_); IMP_XDATA_KEY(AecDbXCamera, _width_); IMP_XDATA_KEY(AecDbXCamera, _height_); IMP_XDATA_KEY(AecDbXCamera, _ptOutput_); IMP_XDATA_KEY(AecDbXCamera, _horiztop_); IMP_XDATA_KEY(AecDbXCamera, _horizbottom_); IMP_XDATA_KEY(AecDbXCamera, _usagemode_); typedef AecDbXCamera::AcDbEntityArray AcDbEntityArray; typedef AecDbXCamera::IDMapEntities IDMapEntities; typedef AecDbXCamera::EntMapEntities EntMapEntities; namespace { // 从母实体上拷贝属性 void copyProperty(AcDbEntity *pSrc, AcDbEntity *pDes) { pDes->setLayer(pSrc->layerId()); pDes->setLinetype(pSrc->linetypeId()); pDes->setColorIndex(pSrc->colorIndex()); AecDbObjXDataMap xdata; if (xdata.Read(pSrc, BIMDATA_APP)) xdata.Write(pDes, BIMDATA_APP); AcDbPolyline *pPlSrc(AcDbPolyline::cast(pSrc)), *pPlDes(AcDbPolyline::cast(pDes)); if (pPlSrc && pPlDes) { double dW; if (pPlSrc->getConstantWidth(dW) == Acad::eOk) pPlDes->setConstantWidth(dW); } } // 辅助函数:使用射线法判断一个点是否在闭合曲线上 bool IsPointInsideBoundary(AcDbCurve *pBoundary, const AcGePoint3d &testPt) { if (pBoundary == NULL) { return false; } // 1. 优先判定:点是否在边界曲线上 AcGePoint3d closestPt; if (pBoundary->getClosestPointTo(testPt, closestPt) == Acad::eOk) { // 如果测试点到边界最近点的距离小于容差,认为点在边界上 if (testPt.distanceTo(closestPt) < 1e-6) { return true; // 视为在内部,予以保留 } } // 2. 获取边界的外包围盒,用于快速排除并构建射线长度 AcDbExtents extents; if (pBoundary->getGeomExtents(extents) != Acad::eOk) { return false; } // 粗略判断:如果点在外包围盒之外,肯定在外部 if (testPt.x < extents.minPoint().x || testPt.x > extents.maxPoint().x || testPt.y < extents.minPoint().y || testPt.y > extents.maxPoint().y) { return false; } // 3. 构造一条射线,从测试点射向包围盒外的一个极远点 // 使用非标准角度的向量,尽量避免穿过顶点或与边重合 AcGeVector3d rayDir(1.0, 0.314159, 0.0); double dist = extents.maxPoint().distanceTo(extents.minPoint()) * 2.0; AcGePoint3d farPt = testPt + rayDir * dist; AcDbLine rayLine(testPt, farPt); AcGePoint3dArray intPts; // 4. 求交 if (pBoundary->intersectWith(&rayLine, AcDb::kOnBothOperands, intPts) != Acad::eOk) { return false; } // 5. 过滤重复交点 (容差处理,防止同一个交点被重复计算) int validIntersectionCount = 0; for (int i = 0; i < intPts.length(); ++i) { bool isDuplicate = false; for (int j = 0; j < i; ++j) { if (intPts[i].distanceTo(intPts[j]) < 1e-6) { isDuplicate = true; break; } } if (!isDuplicate) { validIntersectionCount++; } } // 6. 射线法核心:交点个数为奇数则在内部,偶数则在外部 return (validIntersectionCount % 2) != 0; } // 辅助函数 2:曲线内外判定 bool IsCurveInsideBoundary(AcDbCurve *pBoundary, AcDbCurve *pCurve) { if (!pBoundary || !pCurve) return false; double startParam(.0), endParam(.0); AcGePoint3d midPt; if (pCurve->getStartParam(startParam) == Acad::eOk && pCurve->getEndParam(endParam) == Acad::eOk && pCurve->getPointAtParam((startParam + endParam) * 0.5, midPt) == Acad::eOk) { return IsPointInsideBoundary(pBoundary, midPt); } return false; } // 辅助函数 3:按需克隆 void CloneIfInside(AcDbCurve *pBoundary, AcDbCurve *pTarget, AcDbEntityArray &output) { if (IsCurveInsideBoundary(pBoundary, pTarget)) { AcDbEntity *pClone = static_cast(pTarget->clone()); if (pClone) { copyProperty(pTarget, pClone); output.append(pClone); } } } // 主控裁剪函数 void ClipCurvesByBoundary(AcDbCurve *pBoundary, const AcDbEntityArray &ptrs, AcDbEntityArray &output) { if (!pBoundary) return; if (ptrs.isEmpty()) return; double param(.0); AcGePoint3d projPt(AcGePoint3d::kOrigin); AcGePoint3dArray intPts; AcGeDoubleArray splitParams; std::vector vecParams; AcDbVoidPtrArray curveFragments; for (int i = 0; i < ptrs.length(); ++i) { AcDbCurve *pTargetCurve = AcDbCurve::cast(ptrs[i]); if (!pTargetCurve) continue; intPts.removeAll(); // 1. 获取交点 if (pTargetCurve->intersectWith(pBoundary, AcDb::kOnBothOperands, intPts) != Acad::eOk) continue; // 2. 无交点处理 if (intPts.length() < 1) { CloneIfInside(pBoundary, pTargetCurve, output); continue; } splitParams.removeAll(); vecParams.clear(); // 3. 交点转参数 for (int j = 0; j < intPts.length(); ++j) { if (pTargetCurve->getClosestPointTo(intPts[j], projPt) != Acad::eOk) continue; if (pTargetCurve->getParamAtPoint(projPt, param) != Acad::eOk) continue; vecParams.push_back(param); } // 4. 参数排序去重与容错 if (vecParams.empty()) { CloneIfInside(pBoundary, pTargetCurve, output); continue; } std::sort(vecParams.begin(), vecParams.end()); vecParams.erase(std::unique(vecParams.begin(), vecParams.end()), vecParams.end()); for (size_t k = 0; k < vecParams.size(); ++k) { splitParams.append(vecParams[k]); } // 5. 打断曲线与容错 curveFragments.removeAll(); if (pTargetCurve->getSplitCurves(splitParams, curveFragments) != Acad::eOk) { CloneIfInside(pBoundary, pTargetCurve, output); continue; } // 6. 遍历碎片(经过重构,这里现在犹如散文般清晰) for (int f = 0; f < curveFragments.length(); ++f) { AcDbCurve *pFragment = AcDbCurve::cast((AcDbEntity *)curveFragments[f]); if (!pFragment) continue; // 直接复用逻辑判定 if (IsCurveInsideBoundary(pBoundary, pFragment)) { // 内部保留,转移控制权 copyProperty(pTargetCurve, pFragment); output.append(pFragment); } else { // 外部剔除,或底层参数异常,统一就地销毁 delete pFragment; } } } } void clipResultBySection(IDMapEntities &result, EntMapEntities &result2, AcDbCurve *pSection) { if (!pSection) return; AcDbEntityArray output; IDMapEntities::iterator it(result.begin()); for (; it != result.end(); ++it) { // output的内容会转移到it->second内, // 会在外部清理,这里removeall即可 output.removeAll(); // 取出每个id关联的结果,和pSection进行clip运算 ClipCurvesByBoundary(pSection, it->second, output); // 清理 it->second 的内容,置换为 output deleteContainerOfArx(it->second); if (!output.isEmpty()) it->second.append(output); } EntMapEntities::iterator it2(result2.begin()); for (; it2 != result2.end(); ++it2) { output.removeAll(); ClipCurvesByBoundary(pSection, it2->second, output); deleteContainerOfArx(it2->second); if (!output.isEmpty()) it2->second.append(output); } } // 删除一个实体,如果是块引用,则尽量删除其块 void eraseEnt(AcDbObjectId &id, Adesk::Boolean erasing = Adesk::kTrue) { AcDbObjectPointer entRef(id, AcDb::kForWrite); if (entRef.openStatus() == Acad::eOk) { AcDbObjectId idBlk = entRef->blockTableRecord(); if (entRef->erase(erasing) == Acad::eOk) { AcDbBlockTableRecordPointer entTblRec(idBlk, AcDb::kForWrite); if (entTblRec.openStatus() == Acad::eOk) { AcDbObjectIdArray ar; entTblRec->getBlockReferenceIds(ar); if (ar.isEmpty()) entTblRec->erase(erasing); } } } else { AcDbEntityPointer ent(id, AcDb::kForWrite); if (ent.openStatus() == Acad::eOk) ent->erase(erasing); } } AcGeVector3d getViewDir() { AcGePoint3dArray pts; struct resbuf rb; acedGetVar(_T("viewdir"), &rb); ads_point dirPt; acdbUcs2Wcs(rb.resval.rpoint, dirPt, Adesk::kTrue); return asVec3d(dirPt); } bool Grip_WorldDrawfunc(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId &entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize) { AcGiFillType eOldFill = pWd->subEntityTraits().fillType(); int nOldColor = pWd->subEntityTraits().color(); AecDbXCamera::GripData *pGrip = (AecDbXCamera::GripData *)pThis->appData(); AcGePoint3d ptGe[5], ptBox[5]; AcGePoint3d ptGrip = pThis->gripPoint(); double dOne = CoreTools::PixelToWcs(1); ptGe[0] = ptGrip; ptGe[0].x -= 4 * dOne; ptGe[1] = ptGrip; ptGe[1].x += 4 * dOne; ptBox[0] = ptGe[0]; ptBox[0].y -= 4 * dOne; ptBox[1] = ptGe[0]; ptBox[1].y += 4 * dOne; ptBox[2] = ptGe[1]; ptBox[2].y += 4 * dOne; ptBox[3] = ptGe[1]; ptBox[3].y -= 4 * dOne; AcGeVector3d vtNow(getViewDir()); if (!vtNow.isCodirectionalTo(AcGeVector3d::kZAxis)) { AcGePlane pln(ptGrip, vtNow); AcGeVector3d X, Y; pln.getCoordSystem(ptGrip, X, Y); AcGeMatrix3d mat; mat.setToAlignCoordSys(ptGrip, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis , ptGrip, X, Y, vtNow); ptBox[0].transformBy(mat); ptBox[1].transformBy(mat); ptBox[2].transformBy(mat); ptBox[3].transformBy(mat); } pWd->subEntityTraits().setFillType(kAcGiFillAlways); pWd->geometry().polygon(4, ptBox); pWd->subEntityTraits().setFillType(eOldFill); // 有frame数据就画线 if (pGrip->m_mode == AecDbXCamera::eVerti && pGrip->m_arSelectFrame.length() > 3) { AcGePoint3d arFrame1[] = { pGrip->m_arSelectFrame[1] , pGrip->m_arSelectFrame[2] , pGrip->m_arSelectFrame[3] , pGrip->m_arSelectFrame[0] }; pWd->subEntityTraits().setColor(9); pWd->geometry().polyline(4, arFrame1); if (pGrip->m_arSelectFrame.length() > 7) { // 画下层线 AcGePoint3d arFrame2[] = { pGrip->m_arSelectFrame[4] , pGrip->m_arSelectFrame[5] , pGrip->m_arSelectFrame[6] , pGrip->m_arSelectFrame[7] , pGrip->m_arSelectFrame[4] }; pWd->geometry().polyline(5, arFrame2); AcGePoint3d arFrame3[2] = { pGrip->m_arSelectFrame[0], pGrip->m_arSelectFrame[4] }; pWd->geometry().polyline(2, arFrame3); arFrame3[0] = pGrip->m_arSelectFrame[1]; arFrame3[1] = pGrip->m_arSelectFrame[5]; pWd->geometry().polyline(2, arFrame3); arFrame3[0] = pGrip->m_arSelectFrame[2]; arFrame3[1] = pGrip->m_arSelectFrame[6]; pWd->geometry().polyline(2, arFrame3); arFrame3[0] = pGrip->m_arSelectFrame[3]; arFrame3[1] = pGrip->m_arSelectFrame[7]; pWd->geometry().polyline(2, arFrame3); } pWd->subEntityTraits().setColor(nOldColor); } else if (pGrip->m_mode == AecDbXCamera::eHoriz && pGrip->m_arSelectFrame.length() > 7) { pWd->subEntityTraits().setColor(9); AcGePoint3d ar[] = { pGrip->m_arSelectFrame[5] , pGrip->m_arSelectFrame[6] , pGrip->m_arSelectFrame[7] , pGrip->m_arSelectFrame[4] , pGrip->m_arSelectFrame[5] }; pWd->geometry().polyline(5, ar); AcGePoint3d arFrame[2] = { pGrip->m_arSelectFrame[1], pGrip->m_arSelectFrame[5] }; pWd->geometry().polyline(2, arFrame); arFrame[0] = pGrip->m_arSelectFrame[0]; arFrame[1] = pGrip->m_arSelectFrame[4]; pWd->geometry().polyline(2, arFrame); arFrame[0] = pGrip->m_arSelectFrame[2]; arFrame[1] = pGrip->m_arSelectFrame[6]; pWd->geometry().polyline(2, arFrame); arFrame[0] = pGrip->m_arSelectFrame[3]; arFrame[1] = pGrip->m_arSelectFrame[7]; pWd->geometry().polyline(2, arFrame); pWd->subEntityTraits().setColor(nOldColor); } if (pGrip->m_bDrawResultFrame) { AcGePoint3d arFrame[] = { pGrip->m_arResultFrame[1] , pGrip->m_arResultFrame[2] , pGrip->m_arResultFrame[3] , pGrip->m_arResultFrame[0] , pGrip->m_arResultFrame[1] }; pWd->subEntityTraits().setColor(6); pWd->geometry().polyline(5, arFrame); pWd->subEntityTraits().setColor(nOldColor); } return true; } AcDbViewport *makeViewPort(const AcGePoint3d &ptVp // 视口起始点 , const AcGeVector3d &vtVp) // 视口方向和长度 { AcDbViewport *pVp = new AcDbViewport; pVp->setViewTarget(ptVp - vtVp); pVp->setViewDirection(vtVp); pVp->setFrontClipDistance(vtVp.length()); pVp->setBackClipDistance(0); pVp->setFrontClipOn(); pVp->setBackClipOn(); return pVp; } //HINSTANCE _getHLRInstance() //{ // DWORD dRes = 0; // CString sSHHLrDll, sDbx; // if (!CoreTools::FindSHHLrDll(sSHHLrDll, sDbx)) // { // acutPrintf(_T("\n没有找到 SHHLr.dll 或 AsdkHlrApi.lib 文件!")); // return NULL; // } // HINSTANCE hDllInst(NULL); // if (hDllInst == NULL) // { // DWORD dw = ::GetCurrentDirectory(0, NULL); // CString wkd; // ::GetCurrentDirectory(dw + 1, wkd.GetBuffer(dw + 1)); // wkd.ReleaseBuffer(); // ::SetCurrentDirectory(sDbx); // hDllInst = ::GetModuleHandle(sSHHLrDll); // if (!hDllInst) // hDllInst = ::LoadLibrary(sSHHLrDll); // dRes = GetLastError(); // ::SetCurrentDirectory(wkd); // } // return hDllInst; //} //typedef void(_cdecl *hlr_collect_all)(AcDbObjectIdArray & // 原始实体 // , AcDbEntityArray & // 原始实体的指针,如果实体没有ID的情况下,用此参数传入 // , const int & // 控制参数 // , AcDbViewport * // 视口 // , IDMapEntities & // 结果,first-原实体 second-生成的消隐实体 // , EntMapEntities &); // 结果,first-原实体 second-生成的消隐实体 //typedef void(_cdecl *hlr_collect_simple)(AcDbObjectIdArray & // , const int & // , AcDbViewport * // , IDMapEntities &); void HlrCalc_simple(AcDbObjectIdArray &arIds , AcDbViewport *pVp , const int &control , IDMapEntities &result) { HLR::hlr_collect(arIds, control, pVp, result); // HINSTANCE hDllInst(getHLRInstance()); // if (!hDllInst) // { // acutPrintf(_T("\n加载 HLR 失败")); // return; // } // hlr_collect_simple ptrFunc = (hlr_collect_simple)GetProcAddress(hDllInst, "hlr_collect"); // if (ptrFunc != NULL) // ptrFunc(arIds, control, pVp, result); //#ifndef ZWCAD // if (::FreeLibrary(hDllInst)) // hDllInst = NULL; //#endif } void HlrCalc(AcDbObjectIdArray &arIds , AcDbEntityArray & arPtrs , AcDbViewport *pVp , const int &control , IDMapEntities &result , EntMapEntities& result2) { HLR::hlr_collect_all(arIds, arPtrs, control, pVp, result, result2); // HINSTANCE hDllInst(getHLRInstance()); // if (!hDllInst) // { // acutPrintf(_T("\n加载 HLR 失败")); // return; // } // hlr_collect_all ptrFunc = (hlr_collect_all)GetProcAddress(hDllInst, "hlr_collect_all"); // if (ptrFunc != NULL) // ptrFunc(arIds, arPtrs, control, pVp, result, result2); //#ifndef ZWCAD // if (::FreeLibrary(hDllInst)) // hDllInst = NULL; //#endif } bool zeroLength(AcDbCurve *pCrv, const double &tol) { double dPEnd(.0), dDist(.0); pCrv->getEndParam(dPEnd); pCrv->getDistAtParam(dPEnd, dDist); return COMPARE_DOUBLE::equal_zero(dDist, tol); } void rollback(const AcDbObjectIdArray &arids) { AcDbEntityArray ar, output; EntMapEntities eme; for (int i(0); i < arids.length(); ++i) { AcDbEntityPointer ent(arids[i], AcDb::kForRead); if (ent.openStatus() != Acad::eOk) continue; AecDbEntityBase *pEnt(AecDbEntityBase::cast(ent)); AecDbCurveBase *pCrv(AecDbCurveBase::cast(ent)); if (pEnt) pEnt->ProcessHlrResult(ar, eme, output); if (pCrv) pCrv->ProcessHlrResult(ar, eme, output); } } bool isEnvelope(AcDbObjectId id) { AcDbEntityPointer ent(id, AcDb::kForRead); if (ent.openStatus() != Acad::eOk) return false; CString sDXF(ent->isA()->dxfName()); if (HlrCutOption::isEnvelopeEntity(sDXF)) { // 板需要判断一下,如果有填充,不属于构筑物 if (sDXF == _T("AEC_DBSLAB")) { AecDbEwPipeBase *p(AecDbEwPipeBase::cast(ent)); PipeHatch ph; if (p) return !p->GetHatch(ph); else return false; } return true; } else return false; return false; } bool isValidSolid(AcDb3dSolid *pSolid) { AcDbExtents ext; if (pSolid->isNull()) return false; if (pSolid->getGeomExtents(ext) == Acad::eOk) { double dL = ext.maxPoint().distanceTo(ext.minPoint()); if (COMPARE_DOUBLE::equal_zero(dL)) return false; } else return false; double volume; AcGePoint3d centroid; double momInertia[3], prodInertia[3], prinMoments[3], radiiGyration[3]; AcGeVector3d prinAxes[3]; if (pSolid->getMassProp(volume , centroid , momInertia , prodInertia , prinMoments , prinAxes , radiiGyration , ext) == Acad::eOk) { double dL = ext.maxPoint().distanceTo(ext.minPoint()); if (COMPARE_DOUBLE::equal_zero(dL)) return false; if (COMPARE_DOUBLE::equal_zero(volume)) return false; } else return false; return true; } AcDbEntity* mergeEnvelope(AcDbObjectIdArray &arids) { std::map debugMM; AcDbVoidPtrArray arptrs; AcDbVoidPtrArray _ar; AecDbObjXDataMap *pXDataMap(NULL); for (int i(0); i < arids.length(); ++i) { AcDbEntityPointer ent(arids[i], AcDb::kForRead); if (ent.openStatus() != Acad::eOk) continue; _ar.removeAll(); AecDbEntityBase *pEnt(AecDbEntityBase::cast(ent)); AecDbCurveBase *pCrv(AecDbCurveBase::cast(ent)); if (pEnt) { pEnt->GetDraw3dables(_ar, true); for (int i(0); i < _ar.length(); ++i) debugMM.insert(std::make_pair(_ar[i], ent->id().handle())); arptrs.append(_ar); pXDataMap = pEnt->GetSpecialtyData(AcDb::kForRead); } if (pCrv) { pCrv->GetDraw3dables(_ar, true); for (int i(0); i < _ar.length(); ++i) debugMM.insert(std::make_pair(_ar[i], ent->id().handle())); arptrs.append(_ar); pXDataMap = pCrv->GetSpecialtyData(AcDb::kForRead); } } if (arptrs.isEmpty()) return NULL; // 找到第一个 3dsolid AcDb3dSolid *pSolidAll(NULL); for (int i(0); i < arptrs.length(); ++i) { AcDbEntity *pEnt((AcDbEntity *)arptrs[i]); if (!pEnt) continue; pSolidAll = AcDb3dSolid::cast(pEnt); if (!pSolidAll) continue; if (pSolidAll->isNull()) { #ifndef NDEBUG acutPrintf(_T("\nThe 3DSOLID does not have a ShapeManager object. ")); #endif continue; } arptrs.removeAt(i); break; } if (!pSolidAll) return NULL; if (arptrs.isEmpty()) return pSolidAll; std::map::const_iterator debugIt(debugMM.end()); TCHAR szHand[19]; for (int i(0); i < arptrs.length(); ++i) { AcDbEntity *pEnt((AcDbEntity *)arptrs[i]); if (!pEnt) continue; AcDb3dSolid *pSolid(AcDb3dSolid::cast(pEnt)); if (!pSolid) continue; if (pSolid->isNull()) { #ifndef NDEBUG acutPrintf(_T("\nThe 3DSOLID does not have a ShapeManager object. ")); #endif continue; } if (!isValidSolid(pSolid)) continue; if (pSolidAll->booleanOper(AcDb::kBoolUnite, pSolid) != Acad::eOk) { debugIt = debugMM.find((void*)pSolid); if (debugIt == debugMM.end()) acutPrintf(_T("\n 融合出现错误,构筑物将按照不融和处理。%d"), i); else { memset(szHand,0,sizeof(szHand) ); debugIt->second.getIntoAsciiBuffer(szHand); acutPrintf(_T("\n 融合出现错误,构筑物将按照不融和处理。%s"), szHand); } deleteArrayVoidPtrs(arptrs); DELETE_PTR(pSolidAll); return NULL; } } deleteArrayVoidPtrs(arptrs); return pSolidAll; } // 处理一下构筑物的结果 // 1. 重复线 // 2. 争取处理一下融合构筑物,在二维条件下 void fixEnvelopeResult(AcDbEntityArray &arEnve) { } // 给出中心点及长宽,得到一个矩形,左下角点开始,逆时针方向 AcDbRegion* getRect(const AcGePoint3d &ptCenter , const double &W , const double &H , const AcGeVector3d &vtX = AcGeVector3d::kXAxis , const AcGeVector3d &vtZ = AcGeVector3d::kZAxis) { AcGeVector3d Y(vtX), X(vtX); Y.rotateBy(PI * .5, vtZ); Y.normalize(); X.normalize(); AcGePoint3d pt0 = ptCenter - X * (W * .5); pt0 -= Y * (H * .5); AcGePoint3d pt1 = pt0 + X * W; AcGePoint3d pt2 = pt1 + Y * H; AcGePoint3d pt3 = pt2 - X * W; AcDbVoidPtrArray ar; ar.append(new AcDbLine(pt0, pt1)); ar.append(new AcDbLine(pt1, pt2)); ar.append(new AcDbLine(pt2, pt3)); ar.append(new AcDbLine(pt3, pt0)); AcDbRegion *pReg(CoreTools::createRegion(ar)); deleteArrayVoidPtrs(ar); return pReg; } void processEnvelope(AcDbEntityArray &arEnve) { if (HlrCutOption::getHlrMERGE_Envelope()) { // 构筑物融合后的数据 // 处理一下重复线,设置一下属性 fixEnvelopeResult(arEnve); double dW(.0); if (HlrCutOption::getHlrLW_Envelope(dW)) { for (int i(0); i < arEnve.length(); ++i) { AcDbCurve *pCrv((AcDbCurve*)arEnve[i]); AcDbPolyline *pL(CoreTools::MakePolyline(pCrv)); if (pL) { pL->setConstantWidth(dW); DELETE_PTR(pCrv); arEnve[i] = pL; } } } int nClr(256); AcDbObjectId idLayer(AcDbObjectId::kNull), idLinetype(AcDbObjectId::kNull); BOOL bLayer = HlrCutOption::getHlrLY_Envelope(idLayer); BOOL bLinetype = HlrCutOption::getHlrLT_Envelope(idLinetype); BOOL bClr = HlrCutOption::getHlrCL_Envelope(nClr); for (int i(0); i < arEnve.length(); ++i) { AcDbEntity *pEnt(arEnve[i]); if (bLayer && idLayer.isValid()) pEnt->setLayer(idLayer); if (bLinetype && idLinetype.isValid()) pEnt->setLinetype(idLinetype); if (bClr) pEnt->setColorIndex(nClr); } } else { // 构筑物未融合,每个实体都带有信息,不需要额外操作 // 处理一下重复线 fixEnvelopeResult(arEnve); } } void preprocess(AcDbObjectIdArray &arids // 这个集合会被挑选修改 , const AcGePoint3d &ptPlnO , const AcGeVector3d &vtPlnN , IDMapEntities &preID2Ent // 由 “数据库实体” 产生的补充实体 , AcDbEntityArray &preEnt // 由 “非数据库实体” 产生的补充实体(没有ID与之对应) , AcDbEntityArray &arAll ) { AcDbObjectIdArray arOther; // 目前只有构筑物融合需要 if (HlrCutOption::getHlrMERGE_Envelope()) { AcDbObjectIdArray arEnev; AecDbXCamera::collectEnvelope(arids, arOther, arEnev); AcDbEntity *pEnvelope = mergeEnvelope(arEnev); if (pEnvelope) { arids = arOther; {// 暂时标记一下 AecDbObjXDataMap xData; xData.SetAt(_T("TYPE"), _T("ENVELOPE")); xData.Write(pEnvelope, _T("_ENVELOPE_")); } arAll.append(pEnvelope); preEnt.append(pEnvelope); } else { arOther = arids; } } else arOther.append(arids); AcDbEntityArray ar; for (int i(0); i < arOther.length(); ++i) { AcDbEntityPointer ent(arids[i], AcDb::kForRead); if (ent.openStatus() != Acad::eOk) continue; ar.removeAll(); AecDbEntityBase *pEnt(AecDbEntityBase::cast(ent)); AecDbCurveBase *pCrv(AecDbCurveBase::cast(ent)); if (pEnt) pEnt->PreprocessForHlr(ptPlnO, vtPlnN, ar); if (pCrv) pCrv->PreprocessForHlr(ptPlnO, vtPlnN, ar); if (!ar.isEmpty()) { preID2Ent.insert(std::make_pair(arids[i], ar)); arAll.append(ar); } } } void process_result( const IDMapEntities &result1 , const EntMapEntities &result2 , const IDMapEntities &mpAdditional , const AcDbEntityArray &arAdditional , IDMapEntities &outputWithID , AcDbEntityArray &outputWithoutID ) { AcDbEntityArray entAr; EntMapEntities mpAddi; #if ARX > 23 std::pair prAddi; std::pair prOutput; #else EntMapEntities::_Pairib prAddi; IDMapEntities::_Pairib prOutput; #endif // 构筑物产生的结果 AcDbEntityArray arEnvelope; // 先处理 arAdditional 里面的数据 // arAdditional 里面是不在数据库里面的实体 // 把它的结果从 result2 里面挑出来 AecDbObjXDataMap xData; for (int i(0); i < arAdditional.length(); ++i) { EntMapEntities::const_iterator it(result2.begin()); for (; it != result2.end(); ++it) { if (it->first == arAdditional[i]) { AcDbEntity *pSrc(it->first); const AcDbEntityArray &arResult(it->second); // 计算结果 if (xData.Read(pSrc, _T("_ENVELOPE_"))) { // 说明是构筑物,统一处理,这个分支一般是选择了构筑物融合后参与计算 for (int i(0); i != arResult.length(); ++i) arEnvelope.append((AcDbEntity*)arResult[i]->clone()); continue; } for (int i(0); i != arResult.length(); ++i) { AcDbEntity *pEnt = (AcDbEntity *)arResult[i]->clone(); if (!pEnt) continue; pEnt->setLayer(pSrc->layerId()); pEnt->setLinetype(pSrc->linetypeId()); pEnt->setColorIndex(pSrc->colorIndex()); entAr.append(pEnt); outputWithoutID.append(entAr); } } } } // 不能只查找 result1 的结果 // 因为,如果一个实体的araw3d没有画出任何内容时,result1 里面没有其ID // 但是,result2 却有可能存在它的补充实体 // 下面,对 result1 进行补充 IDMapEntities __result1(result1); IDMapEntities::const_iterator _itAdd(mpAdditional.begin()); for (; _itAdd != mpAdditional.end(); ++_itAdd) { const AcDbObjectId &id(_itAdd->first); const AcDbEntityArray &ar(_itAdd->second); for (int i(0); i < ar.length(); ++i) { EntMapEntities::const_iterator it(result2.begin()); for (; it != result2.end(); ++it) { if (ar.find(it->first) != -1) // it->first 是 id 的补充实体 { // 如果,此时,result1 里面没有这个 id 的话 // 说明 这个实体的draw3d没有结果,但是有补充实体 // 需要把这个id放到result1中。 // 不需要判断,直接插入,如果result1里面有这个id,插会失败 __result1.insert(std::make_pair(id, AcDbEntityArray())); } } } } AcDbVoidPtrArray subAr; IDMapEntities::const_iterator it1(__result1.begin()); for (; it1 != __result1.end(); ++it1) { entAr.removeAll(); mpAddi.clear(); const AcDbObjectId &id(it1->first); const AcDbEntityArray &arDraw3d(it1->second); AcDbEntityPointer ent(id, AcDb::kForRead); if (ent.openStatus() != Acad::eOk) { // 如果 ent 无效,但是还存在结果,将结果复制到 output // 目前只有水平轴网 for (int i(0); i < arDraw3d.length(); ++i) { AcDbEntity *pEnt = AecDbXCamera::cloneObject(arDraw3d[i]); if (!pEnt) continue; entAr.append(pEnt); } } else { // 查询这个 id 有没有补充实体 IDMapEntities::const_iterator itAddi(mpAdditional.find(id)); if (itAddi != mpAdditional.end()) { // 有补充实体,在 result2 里面找到补充实体的结果 for (int i(0); i < itAddi->second.length(); ++i) { // 补充实体 AcDbEntity *pAddi(itAddi->second[i]); EntMapEntities::const_iterator it2 = result2.find(pAddi); if (it2 != result2.end()) { // 补充实体 的 结果 const AcDbEntityArray &ar(it2->second); prAddi = mpAddi.insert(std::make_pair(pAddi, ar)); if (!prAddi.second) prAddi.first->second.append(ar); } } } AecDbEntityBase *pEnt(AecDbEntityBase::cast(ent)); AecDbCurveBase *pCrv(AecDbCurveBase::cast(ent)); if (pEnt) pEnt->ProcessHlrResult(arDraw3d, mpAddi, entAr); else if (pCrv) pCrv->ProcessHlrResult(arDraw3d, mpAddi, entAr); else // 非上华实体 { AcDbBlockReference *pRef(AcDbBlockReference::cast(ent)); AcDbObjectId layerID(ent->layerId()), linetypeID(ent->linetypeId()); int color(ent->colorIndex()); for (int i(0); i < arDraw3d.length(); ++i) { AcDbEntity *pEnt = (AcDbEntity *)arDraw3d[i]->clone(); if (!pEnt) continue; if (pRef) { // 如果被剖切的实体是块,收集结果,方便后面再打成块 subAr.append(pEnt); } else { pEnt->setLayer(layerID); pEnt->setLinetype(linetypeID); pEnt->setColorIndex(color); entAr.append(pEnt); } } if (pRef && !subAr.isEmpty()) { // 如果 ent 是 块参照,它不会有补充实体,结果需要打成块 // 块的属性和 pRef 一样 AcDbBlockReference *pSubRef = CoreTools::makeBlockReference(subAr, NULL); subAr.removeAll(); if (pSubRef) { pSubRef->setLayer(layerID); pSubRef->setLinetype(linetypeID); pSubRef->setColorIndex(color); entAr.append(pSubRef); } } EntMapEntities::const_iterator it(mpAddi.begin()); for (; it != mpAddi.end(); ++it) { layerID = it->first->layerId(); linetypeID = it->first->linetypeId(); color = it->first->colorIndex(); for (int i(0); i < it->second.length(); ++i) { AcDbEntity *pEnt = (AcDbEntity *)it->second[i]->clone(); if (!pEnt) continue; pEnt->setLayer(layerID); pEnt->setLinetype(linetypeID); pEnt->setColorIndex(color); entAr.append(pEnt); } } } if (entAr.isEmpty()) continue; } prOutput = outputWithID.insert(std::make_pair(id, entAr)); if (!prOutput.second) prOutput.first->second.append(entAr); } // 收集构筑物产生的结果(一般是不对构筑物进行融合的情况下) IDMapEntities::iterator it(outputWithID.begin()); for (; it != outputWithID.end(); ++it) { if (!isEnvelope(it->first)) continue; // 是构筑物结果,复制出来,并且删掉outputWithID里面的内容 for (int i(0); i < it->second.length(); ++i) arEnvelope.append((AcDbEntity*)(it->second[i]->clone())); deleteContainerOfArx(it->second); outputWithID.erase(it); it = outputWithID.begin(); } // 处理构筑物 processEnvelope(arEnvelope); outputWithoutID.append(arEnvelope); } } ACRX_DXF_DEFINE_MEMBERS(AecDbXCamera, AecDbEntityBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_XCAMERA, "AecXDbCamera" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") // kCurrentVersionNumber->2 --- 增加 m_arSelectionSet Adesk::UInt32 AecDbXCamera::kCurrentVersionNumber = 2; static const Adesk::UInt16 kBlue = 5; AecDbXCamera::AecDbXCamera(void) { } AecDbXCamera::~AecDbXCamera(void) { deleteContainerOfArx(m_GripDatas); } Acad::ErrorStatus AecDbXCamera::subErase(Adesk::Boolean erasing) { //for (int i(0); i < m_arResults.length(); ++i) // eraseEnt(m_arResults[i], erasing); return AecDbEntityBase::subErase(erasing); } Acad::ErrorStatus AecDbXCamera::copyFrom(const AcRxObject *pSrc) { AssertWriteEnabled(); AecDbXCamera *pCamera = AecDbXCamera::cast(pSrc); if (pCamera != NULL) { m_mapSpecXData.CopyFrom(pCamera->GetSpecialtyData(AcDb::kForRead)); } return Acad::eOk; } void AecDbXCamera::subList() const { assertReadEnabled(); AecDbEntityBase::subList(); m_mapSpecXData.List(); } Acad::ErrorStatus AecDbXCamera::subTransformBy(const AcGeMatrix3d &xform) { AssertWriteEnabled(); SetEyePoint(GetEyePoint().transformBy(xform)); SetEyeDirect(GetEyeDirect().transformBy(xform)); SetOutputPoint(GetOutputPoint().transformBy(xform)); return Acad::eOk; } Acad::ErrorStatus AecDbXCamera::subGetGripPoints(AcDbGripDataPtrArray &grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d &curViewDir, const int bitflags) const { assertReadEnabled(); AcGePoint3dArray ar; getGripPoints(ar); deleteContainerOfArx(m_GripDatas); AcGeVector3d vtZ(getViewDir()); AcGePoint3dArray pts; if (GetUsageMode() == eVerti) { if (vtZ.isParallelTo(AcGeVector3d::kZAxis)) { // 水平 pts.append(ar[0]); pts.append(ar[1]); pts.append(ar[2]); pts.append(ar[3]); pts.append(ar[4]); pts.append(ar[5]); pts.append(ar.last()); } else { // 非水平 pts.append(ar[4]); pts.append(ar[10]); } // 先把 grippoints 里的点都绘制出来 for (int i(0); i < pts.length(); ++i) { GripData *gpd = new GripData; gpd->m_idx = i; gpd->m_pt = pts.at(i); AcDbGripData *pGripData = new AcDbGripData; pGripData->setGripPoint(pts.at(i)); pGripData->setWorldDraw(Grip_WorldDrawfunc); m_GripDatas.append(gpd); pGripData->setAppData(gpd); grips.append(pGripData); } // 第1个点作为绘制点,绘制虚框 GripData &first = *m_GripDatas.first(); first.m_mode = eVerti; first.m_arSelectFrame.append(ar[0]); first.m_arSelectFrame.append(ar[2]); first.m_arSelectFrame.append(ar[3]); first.m_arSelectFrame.append(ar[5]); if (!vtZ.isParallelTo(AcGeVector3d::kZAxis)) // 非水平,绘制范围框 { first.m_arSelectFrame.append(ar[6]); first.m_arSelectFrame.append(ar[7]); first.m_arSelectFrame.append(ar[8]); first.m_arSelectFrame.append(ar[9]); } } else if (GetUsageMode() == eHoriz) { if (vtZ.isParallelTo(AcGeVector3d::kZAxis)) { pts.append(ar[0]); pts.append(ar[1]); pts.append(ar[2]); pts.append(ar[3]); pts.append(ar[4]); pts.append(ar.last()); } else // 非水平,放入 9-10 { pts.append(ar[9]); pts.append(ar[10]); } for (int i(0); i < pts.length(); ++i) { GripData *gpd = new GripData; gpd->m_idx = i; gpd->m_pt = pts.at(i); AcDbGripData *pGripData = new AcDbGripData; pGripData->setGripPoint(pts.at(i)); pGripData->setWorldDraw(Grip_WorldDrawfunc); m_GripDatas.append(gpd); pGripData->setAppData(gpd); grips.append(pGripData); } if (!vtZ.isParallelTo(AcGeVector3d::kZAxis)) // 非水平,绘制范围框 { // 第1个点作为绘制点,绘制虚框 GripData &first = *m_GripDatas.first(); first.m_mode = eHoriz; first.m_arSelectFrame.append(ar[0]); first.m_arSelectFrame.append(ar[1]); first.m_arSelectFrame.append(ar[2]); first.m_arSelectFrame.append(ar[3]); first.m_arSelectFrame.append(ar[5]); first.m_arSelectFrame.append(ar[6]); first.m_arSelectFrame.append(ar[7]); first.m_arSelectFrame.append(ar[8]); } } else // eStatic { if (ar.isEmpty()) return Acad::eOk; GripData *gpd = new GripData; gpd->m_idx = 0; gpd->m_pt = ar.last(); AcDbGripData *pGripData = new AcDbGripData; pGripData->setGripPoint(ar.last()); pGripData->setWorldDraw(Grip_WorldDrawfunc); m_GripDatas.append(gpd); pGripData->setAppData(gpd); grips.append(pGripData); } // 显示结果范围 AcGePoint3d ptLT, ptRT, ptRB, ptLB; if (getResultBox(ptLT, ptRT, ptRB, ptLB)) { GripData &first = *m_GripDatas.first(); first.m_bDrawResultFrame = true; first.m_arResultFrame.append(ptLT); first.m_arResultFrame.append(ptRT); first.m_arResultFrame.append(ptRB); first.m_arResultFrame.append(ptLB); } return Acad::eOk; } Acad::ErrorStatus AecDbXCamera::subGetOsnapPoints(AcDb::OsnapMode osnapMode , INT_PTR gsSelectionMark , const AcGePoint3d &pickPoint , const AcGePoint3d &lastPoint , const AcGeMatrix3d &viewXform , AcGePoint3dArray &snapPoints , AcDbIntArray &geomIds) const { AcGePoint3dArray ar; getGripPoints(ar); if (GetUsageMode() != eStatic) { if (GetUsageMode() == eVerti) { snapPoints.append(ar[0]); snapPoints.append(ar[1]); snapPoints.append(ar[2]); snapPoints.append(ar[3]); snapPoints.append(ar[4]); snapPoints.append(ar[5]); snapPoints.append(ar[10]); } else { snapPoints.append(ar[0]); snapPoints.append(ar[1]); snapPoints.append(ar[2]); snapPoints.append(ar[3]); snapPoints.append(ar[4]); } } AcGePoint3d ptLT, ptRT, ptRB, ptLB; if (getResultBox(ptLT, ptRT, ptRB, ptLB)) { snapPoints.append(ptLT); snapPoints.append(ptRT); snapPoints.append(ptRB); snapPoints.append(ptLB); } return Acad::eOk; } Acad::ErrorStatus AecDbXCamera::subMoveGripPointsAt(const AcDbVoidPtrArray &appData , const AcGeVector3d &offset , const int bitflags) { AssertWriteEnabled(); if (appData.isEmpty()) return Acad::eOk; bool bFresh(false); GripData *pAppData = (GripData *)appData.first(); AcGePoint3dArray ar; getGripPoints(ar); if (GetUsageMode() == eVerti) { AcGePoint3d ptOffset(pAppData->m_pt + offset) , ptOrig(pAppData->m_pt) , pt0(ar[0]) , pt1(ar[1]) , pt2(ar[2]) , pt3(ar[3]) , pt4(ar[4]) , pt5(ar[5]) , pt6(ar[6]); AcGeVector3d vt(getViewDir()); if (vt.isCodirectionalTo(AcGeVector3d::kZAxis)) { switch (pAppData->m_idx) { case 3: // 修改视口宽度 case 5: { AcDbLine seg(pt3, pt5); AcGePoint3d ptNew; seg.getClosestPointTo(ptOffset, ptNew, Adesk::kTrue); AcGeVector3d vtOld(pt4 - ptOrig); AcGeVector3d vtNew(pt4 - ptNew); if (vtOld.isCodirectionalTo(vtNew) && vtNew.length() > 100) { SetWidth(vtNew.length() * 2); bFresh = true; } } break; case 1: // 移动眼睛位置 SetEyePoint(GetEyePoint() + offset); bFresh = true; break; case 0: // 旋转 m_vtEye 的方向 { AcGeVector3d vtOld(pt0 - pt2); AcGeVector3d vtNew(ptOffset - pt1); double dAngle = vtOld.angleTo(vtNew, AcGeVector3d::kZAxis); vtNew = GetEyeDirect(); vtNew.rotateBy(dAngle, AcGeVector3d::kZAxis); SetEyeDirect(vtNew); bFresh = true; } break; case 2: // 旋转 m_vtEye 的方向 { AcGeVector3d vtOld(pt2 - pt0); AcGeVector3d vtNew(ptOffset - pt1); double dAngle = vtOld.angleTo(vtNew, AcGeVector3d::kZAxis); vtNew = GetEyeDirect(); vtNew.rotateBy(dAngle, AcGeVector3d::kZAxis); SetEyeDirect(vtNew); bFresh = true; } break; case 4: // 修改 视口的纵深 既 m_vtEye 的长度 { AcDbLine seg(pt0, pt2); AcGePoint3d ptClosed; seg.getClosestPointTo(ptOffset, ptClosed, Adesk::kTrue); AcGeVector3d vtNew(ptOffset - ptClosed); double dist(ptOffset.distanceTo(ptClosed)); if (dist > 100) { SetEyeDirect(vtNew); bFresh = true; } } break; case 6: // 移动输出结果的位置 { moveOutput(offset); bFresh = false; break; } default: break; } } else { switch (pAppData->m_idx) { case 0: SetHorizTop((pAppData->m_pt + offset).z); break; case 1: SetHorizBottom((pAppData->m_pt + offset).z); break; default: break; } } } else if (GetUsageMode() == eHoriz) { AcGePoint3d ptOld, pt2, ptNew, ptClosed, ptEye; AcDbLine lineH, lineV; AcGeVector3d vtEye; AcGeMatrix3d mat; bFresh = true; AcGeVector3d vtZ(getViewDir()); ptOld = pAppData->m_pt; ptNew = ptOld + offset; if (vtZ.isParallelTo(AcGeVector3d::kZAxis)) { switch (pAppData->m_idx) { case 0: pt2 = ar[2]; SetEyePoint(CoreTools::MidPt(ptNew, pt2)); lineH.setStartPoint(ar[2]); lineH.setEndPoint(ar[3]); lineH.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue); SetHeight(ptNew.distanceTo(ptClosed)); lineV.setStartPoint(ar[1]); lineV.setEndPoint(ar[2]); lineV.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue); SetWidth(ptNew.distanceTo(ptClosed)); break; case 1: pt2 = ar[3]; SetEyePoint(CoreTools::MidPt(ptNew, pt2)); lineH.setStartPoint(ar[2]); lineH.setEndPoint(ar[3]); lineH.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue); SetHeight(ptNew.distanceTo(ptClosed)); lineV.setStartPoint(ar[0]); lineV.setEndPoint(ar[3]); lineV.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue); SetWidth(ptNew.distanceTo(ptClosed)); break; case 2: pt2 = ar[0]; SetEyePoint(CoreTools::MidPt(ptNew, pt2)); lineH.setStartPoint(ar[0]); lineH.setEndPoint(ar[1]); lineH.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue); SetHeight(ptNew.distanceTo(ptClosed)); lineV.setStartPoint(ar[0]); lineV.setEndPoint(ar[3]); lineV.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue); SetWidth(ptNew.distanceTo(ptClosed)); break; case 3: pt2 = ar[1]; SetEyePoint(CoreTools::MidPt(ptNew, pt2)); lineH.setStartPoint(ar[0]); lineH.setEndPoint(ar[1]); lineH.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue); SetHeight(ptNew.distanceTo(ptClosed)); lineV.setStartPoint(ar[2]); lineV.setEndPoint(ar[1]); lineV.getClosestPointTo(ptNew, ptClosed, Adesk::kTrue); SetWidth(ptNew.distanceTo(ptClosed)); break; case 4: // eye SetEyePoint(ptNew); break; case 5: // output moveOutput(offset); bFresh = false; break; default: break; } } else { switch (pAppData->m_idx) { case 0: // top ptEye = GetEyePoint(); ptEye.z = ptNew.z; SetEyePoint(ptEye); SetHorizTop(ptNew.z); vtEye = GetEyeDirect(); vtEye = -AcGeVector3d::kZAxis * (GetHorizTop() - GetHorizBottom()); SetEyeDirect(vtEye); break; case 1: // bottom SetHorizBottom(ptNew.z); vtEye = GetEyeDirect(); vtEye = -AcGeVector3d::kZAxis * (GetHorizTop() - GetHorizBottom()); SetEyeDirect(vtEye); break; default: break; } } } else // eStatic { moveOutput(offset); bFresh = false; } // 当松开夹点时,database() 不为空,可以刷新。 if (database() && bFresh) { refresh(true); } return Acad::eOk; } Acad::ErrorStatus AecDbXCamera::dwgInFields(AcDbDwgFiler *pFiler) { AssertWriteEnabled(); //----- Read parent class information first. Acad::ErrorStatus es = Acad::eOk; if (!pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbEntityBase::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 > AecDbXCamera::kCurrentVersionNumber) return (Acad::eMakeMeProxy); m_mapSpecXData.dwgInFields(pFiler); m_arResults.removeAll(); Adesk::Int32 num(0); pFiler->readInt32(&num); AcDbObjectId id; for (int i(0); i < num; ++i) { pFiler->readSoftPointerId((AcDbSoftPointerId *)&id); if (id.isValid()) m_arResults.append(id); } if (version > 1) { pFiler->readInt32(&num); for (int i(0); i < num; ++i) { pFiler->readSoftPointerId((AcDbSoftPointerId *)&id); if (id.isValid()) m_arSelectionSet.append(id); } } return (pFiler->filerStatus()); } Acad::ErrorStatus AecDbXCamera::dwgOutFields(AcDbDwgFiler *pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = Acad::eOk; if (!pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbEntityBase::dwgOutFields(pFiler); if (es != Acad::eOk) return (es); } //----- Object version number needs to be saved first if ((es = pFiler->writeUInt32(AecDbXCamera::kCurrentVersionNumber)) != Acad::eOk) return (es); m_mapSpecXData.dwgOutFields(pFiler); pFiler->writeInt32(m_arResults.length()); for (int i(0); i < m_arResults.length(); ++i) pFiler->writeSoftPointerId(m_arResults[i]); if (AecDbXCamera::kCurrentVersionNumber > 1) { pFiler->writeInt32(m_arSelectionSet.length()); for (int i(0); i < m_arSelectionSet.length(); ++i) pFiler->writeSoftPointerId(m_arSelectionSet[i]); } return (pFiler->filerStatus()); } Acad::ErrorStatus AecDbXCamera::Draw2d(AcGiDraw &dc) const { assertReadEnabled(); AcGePoint3dArray ar; getGripPoints(ar); Adesk::UInt16 oldClr = dc.GetColor(); dc.SetColor(6); if (GetUsageMode() != eStatic) { int prec(0); CString sTop; sTop.Format(_T("%s , %s"), TypeConvert::d2s(GetHorizTop(), &prec) , TypeConvert::d2s(GetHorizBottom(), &prec)); double dH; AcGePoint3d ptIns; double dRotation(.0); AcGeVector3d X(AcGeVector3d::kXAxis); if (GetUsageMode() == eVerti) { dc.DrawLine(AcGeLineSeg3d(ar[0], ar[2])); dH = (ar[2].distanceTo(ar[3]) * .025); ptIns = (CoreTools::MidPt(ar[0], ar[2]) - GetEyeDirect().normalize() * dH); X = (ar[2] - ar[0]).normalize(); dRotation = AcGeVector3d::kXAxis.angleTo(X, AcGeVector3d::kZAxis); } else { dc.DrawLine(AcGeLineSeg3d(ar[0], ar[1])); dc.DrawLine(AcGeLineSeg3d(ar[1], ar[2])); dc.DrawLine(AcGeLineSeg3d(ar[2], ar[3])); dc.DrawLine(AcGeLineSeg3d(ar[3], ar[0])); dH = (ar[1].distanceTo(ar[2]) * .025); ptIns = (CoreTools::MidPt(ar[3], ar[2]) - AcGeVector3d::kYAxis * dH); } AcDbText txt1; txt1.setTextString(sTop); txt1.setPosition(ptIns); txt1.setHeight(dH); AcDbExtents ext; txt1.getGeomExtents(ext); double dW(ext.maxPoint().x - ext.minPoint().x); ptIns -= X * (dW * .5); txt1.setPosition(ptIns); txt1.setRotation(dRotation); dc.DrawEntity(txt1); } dc.SetColor(oldClr); return Acad::eOk; } Acad::ErrorStatus AecDbXCamera::Draw3d(AcGiDraw &dc) const { return Draw2d(dc); } void AecDbXCamera::cloneObjects(AcDbObjectIdArray &arids, AcDbEntityArray &ents) { for (int i(0); i < arids.length(); ++i) { AcDbEntity *pEnt = cloneObject(arids[i]); if (!pEnt) continue; ents.append(pEnt); } } AcDbEntity *AecDbXCamera::cloneObject(AcDbEntity *p) { if (!p) return NULL; AcDbEntity *pEnt = (AcDbEntity *)p->clone(); if (!pEnt) return NULL; pEnt->setLayer(p->layerId()); pEnt->setLinetype(p->linetypeId()); pEnt->setColorIndex(p->colorIndex()); AecDbObjXDataMap xdata; if (xdata.Read(p, BIMDATA_APP)) xdata.Write(pEnt, BIMDATA_APP); return pEnt; } AcDbEntity *AecDbXCamera::cloneObject(AcDbObjectId &id) { AcDbEntityPointer ent(id, AcDb::kForRead); if (ent.openStatus() != Acad::eOk) return NULL; return cloneObject(ent); } void AecDbXCamera::collectEnities(resbuf *selType, resbuf *selArea, AcDbObjectIdArray &arIds) { ads_name ss, ent; int nRes = acedSSGet(_T("CP"), selArea, NULL, selType, ss); if (nRes != RTNORM) return; Adesk::Int32 lLen = 0; acedSSLength(ss, &lLen); AcDbObjectId id; for (int i = 0; i < lLen; i++) { acedSSName(ss, i, ent); acdbGetObjectId(id, ent); if (id.isValid()) arIds.append(id); } acedSSFree(ss); } resbuf *AecDbXCamera::getCollectArea() const { assertReadEnabled(); AcGePoint3dArray arPts; getGripPoints(arPts); struct resbuf *pointlist(NULL); if (GetUsageMode() == eVerti) { pointlist = acutBuildList(RTPOINT, arPts[0], RTPOINT, arPts[2], RTPOINT, arPts[3], RTPOINT, arPts[5], RTPOINT, arPts[0], 0); } else if (GetUsageMode() == eHoriz) { pointlist = acutBuildList(RTPOINT, arPts[0], RTPOINT, arPts[1], RTPOINT, arPts[2], RTPOINT, arPts[3], RTPOINT, arPts[0], 0); } return pointlist; } void AecDbXCamera::calcRangeOfElev(double &dMax, double &dMin) { AcDbObjectIdArray ar; collectEnities(ar); AcGePoint3d ptmax, ptmin; AcDbExtents ext, all; for (int i(0); i < ar.length(); ++i) { AcDbEntityPointer ent(ar[i], AcDb::kForRead); if (ent.openStatus() != Acad::eOk) continue; if (ent->getGeomExtents(ext) != Acad::eOk) continue; ptmax = ext.maxPoint(); ptmin = ext.minPoint(); if (ptmax.x < ptmin.x || ptmax.y < ptmin.y || ptmax.z < ptmin.z) continue; all.addExt(ext); } dMax = all.maxPoint().z; dMin = all.minPoint().z; if (dMax < dMin) { dMax = 0.; dMin = 0.; } } void AecDbXCamera::collectEnities(AcDbObjectIdArray &arIds) const { assertReadEnabled(); /* struct resbuf *pRb = acutBuildList( -4, _T("") , -4, _T("") , -4, _T("or>") , -4, _T("or>") , -4, _T("") , -4, _T("not>") , 0); */ struct resbuf *selArea(getCollectArea()); struct resbuf *typelist(getSelectTypeResbuf()); collectEnities(typelist, selArea, arIds); acutRelRb(selArea); acutRelRb(typelist); } void AecDbXCamera::transfromHlrResult(const AcGePoint3d &_ptEye , const AcGeVector3d &vtEye , const AcGeVector3d &vtX , const AcGePoint3d &_ptOutput , IDMapEntities &result , EntMapEntities &result2 , AcDbEntity *pSection) { if (!pSection) return; AcDbEntityArray ptrs; IDMapEntities::const_iterator it(result.begin()); for (; it != result.end(); ++it) ptrs.append(it->second); EntMapEntities::const_iterator it2(result2.begin()); for (; it2 != result2.end(); ++it2) ptrs.append(it2->second); ptrs.append(pSection); if (ptrs.isEmpty()) return; AcGeMatrix3d mat; AcGePoint3d ptEye(_ptEye); ptEye.z = .0; mat.setToAlignCoordSys(ptEye , vtX.normal() , vtEye.crossProduct(vtX).normal() , vtEye.normal() , AcGePoint3d::kOrigin , AcGeVector3d::kXAxis , AcGeVector3d::kYAxis , AcGeVector3d::kZAxis); AcGeMatrix3d matVerti; AcGePoint3d ptStart(AcGePoint3d::kOrigin); for (int i(0); i < ptrs.length(); ++i) { AcDbEntity *pEnt((AcDbEntity *)ptrs[i]); if (pEnt) pEnt->transformBy(mat); AcDbCurve *pCrv(AcDbCurve::cast(pEnt)); if (pCrv) { // 拉到0标高 pCrv->getStartPoint(ptStart); matVerti.setTranslation(ptStart.z * -AcGeVector3d::kZAxis); pCrv->transformBy(matVerti); } } // 只需要pSection的中点做移动点 AcDbExtents ext; pSection->getGeomExtents(ext); AcGePoint3d ptResultCenter(CoreTools::MidPt(ext.maxPoint(), ext.minPoint())); AcGePoint3d ptOutput(_ptOutput); ptOutput.z = .0; mat.setToIdentity(); mat.setToTranslation(ptOutput - ptResultCenter); for (int i(0); i < ptrs.length(); ++i) { AcDbEntity *pEnt((AcDbEntity *)ptrs[i]); if (pEnt) pEnt->transformBy(mat); } } void AecDbXCamera::transfromHlrResult(IDMapEntities &result , EntMapEntities &result2 , AcDbEntity *pSection) const { assertReadEnabled(); if (!pSection) return; AcGePoint3dArray arPts; getGripPoints(arPts); AcGeVector3d X(AcGeVector3d::kXAxis); if (GetUsageMode() == eVerti) { if (arPts.length() < 2) return; X = arPts[0] - arPts[1]; } AcGeVector3d Z(-GetEyeDirect()); AcGeVector3d Y(Z.crossProduct(X)); transfromHlrResult(GetEyePoint(), Z, X, GetOutputPoint(), result, result2, pSection); } void AecDbXCamera::hlrCalc(AcDbObjectIdArray &arIds , const AcGePoint3d &ptEye , const AcGeVector3d &vtEye , const AcGeVector3d &vtX , const AcGePoint3d &ptOutput , AcDbPolyline *pSection , IDMapEntities &outputWithID , AcDbEntityArray &outputWithoutID , AcDbEntityArray &arAxisPtrs) { // 在数据库中的实体所生成的补充实体 // first-数据库中实体id second-选中实体产生的补充实体 IDMapEntities mpAdditional; // 不在数据库中的实体生成的补充实体 AcDbEntityArray arAdditional; /* HlrCalc 处理三种类型的数据 1.数据库内的实体 2.数据库内的实体产生的补充实体(管线、管件的中心线,阀门的2D表示 etc.) 3.非数据库内的实体产生的补充实体(构筑物融合之后的实体就属于这种类型) 2、3两个数据都放入arAdditional_all里面进行计算 */ // 所有的补充实体 AcDbEntityArray arAdditional_all; // 预处理,得到选中实体的补充实体 preprocess(arIds , ptEye , vtEye , mpAdditional , arAdditional , arAdditional_all); // 获取hlr原始结果 std::shared_ptr pVp(makeViewPort(ptEye, -vtEye)); IDMapEntities result1; EntMapEntities result2; int control = kEntity|kProgress|kHideTangents|kProject/*|kShowAll|kBlock|kHonorInternals*/; HlrCalc(arIds, arAdditional_all, pVp.get(), control, result1, result2); if (result1.empty() && result2.empty()) { // 如果实体的PreprocessForHlr函数内,设置了 HLR_CALC,从而影响实体的 Draw3d 函数的返回 // 那么,其PreprocessForHlr函数一定要无条件设置回来 // rollback 回调用其内部的PreprocessForHlr函数 rollback(arIds); return; } if (!arAxisPtrs.isEmpty()) result1.insert(std::make_pair(AcDbObjectId::kNull, arAxisPtrs)); // 调整结果位置 transfromHlrResult(ptEye, -vtEye, vtX, ptOutput, result1, result2, pSection); // 截面裁剪 clipResultBySection(result1, result2, pSection); // 如果裁剪之后,没有结果了,回退实体状态 if (result1.empty() && result2.empty()) { rollback(arIds); return; } // 设置属性 process_result(result1, result2, mpAdditional, arAdditional, outputWithID, outputWithoutID); // 最后把section复制一份放到结果里面 //outputWithoutID.append((AcDbEntity*)pSection->clone()); // 释放draw3d的计算结果 IDMapEntities::iterator it(result1.begin()); for (; it != result1.end(); ++it) deleteContainerOfArx(it->second); // 释放补充实体的计算结果 EntMapEntities::iterator it2(result2.begin()); for (; it2 != result2.end(); ++it2) deleteContainerOfArx(it2->second); // 释放 所有补充实体 deleteContainerOfArx(arAdditional_all); rollback(arIds); } void AecDbXCamera::refresh(const bool &bRefreshEntity) { assertWriteEnabled(); if (!bRefreshEntity) return; // 清空输出结果实体 eraseEnts(m_arResults); // 收集实体 AcDbObjectIdArray arIds; // 收集轴网 AcDbObjectIdArray arAxis; // 收集围护结构 if (GetUsageMode() != eStatic) { collectEnities(arIds); collectAxisObject(arAxis); } else { arIds.append(m_arSelectionSet); } if (arIds.isEmpty()) return; AcGeVector3d X(AcGeVector3d::kXAxis); if (GetUsageMode() == eVerti) { AcGePoint3dArray arPts; getGripPoints(arPts); if (arPts.length() < 2) return; X = arPts[0] - arPts[1]; } // 截面 AcDbPolyline *pSection = getSectionPolygon(); IDMapEntities outputWithID; // 可以与数据库实体相关联的结果 AcDbEntityArray outputWithoutID;// 不能与数据库实体相关联的结果 AcDbEntityArray entAxis; // 计算轴网 if (!arAxis.isEmpty()) { if (GetUsageMode() == eVerti) // 垂直剖切,轴网自己遮挡一下 { AcDbExtents extAll; pSection->getGeomExtents(extAll); double dMaxZ(extAll.maxPoint().z), dMinZ(extAll.minPoint().z); double dH(dMaxZ - dMinZ); // 最高点向上延长30% dMaxZ += dH * (3. / 10); // 最低点向上提长度的一半 dMinZ += dH * .5; // 得到特征点 AcGePoint3dArray arPts; getGripPoints(arPts); // 找到和剖切线垂直的,其它的不要 AcGeLineSeg3d cutLine(arPts[1], arPts[0]), axisLine; for (int i(0); i < arAxis.length(); ++i) { AcDbObjectPointer line(arAxis[i], AcDb::kForRead); if (line.openStatus() != Acad::eOk) continue; axisLine.set(line->startPoint(), line->endPoint()); if (axisLine.isPerpendicularTo(cutLine)) entAxis.append(cloneObject(arAxis[i])); } // 将轴网变换到剖切面上 // 以剖切线为轴,翻转轴网 AcGeMatrix3d mat; mat.setToRotation(-PI * .5 , arPts[2] - arPts[1]); AcGePoint3d ptS, ptE; for (int i(0); i < entAxis.length(); ++i) { AcDbLine *pL(AcDbLine::cast(entAxis[i])); if (pL) { pL->transformBy(mat); ptS = pL->startPoint(); ptE = pL->endPoint(); // 修改变换后的标高 pL->setStartPoint(AcGePoint3d(ptS.x, ptS.y, dMinZ)); pL->setEndPoint(AcGePoint3d(ptE.x, ptE.y, dMaxZ)); } } } else if (GetUsageMode() == eHoriz) // 水平剖切,直接复制出来 { // 拷贝轴网 cloneObjects(arAxis, entAxis); } } hlrCalc(arIds , GetEyePoint() , GetEyeDirect() , X , GetOutputPoint() , pSection , outputWithID , outputWithoutID , entAxis ); DELETE_PTR(pSection); // 输出 IDMapEntities::iterator it; AcDbObjectId id; for (it = outputWithID.begin(); it != outputWithID.end(); ++it) { for (int i(0); i < it->second.length(); ++i) { AcDbEntity *pEnt(it->second[i]); if (!pEnt) continue; id = CoreTools::AddToModelSpace(pEnt); if (id.isValid()) m_arResults.append(id); else DELETE_PTR(pEnt); } } for (int i(0); i < outputWithoutID.length(); ++i) { AcDbEntity *pEnt(outputWithoutID[i]); if (!pEnt) continue; id = CoreTools::AddToModelSpace(pEnt); if (id.isValid()) m_arResults.append(id); else DELETE_PTR(pEnt); } // 保险起见,再还原一次 rollback(arIds); } void AecDbXCamera::getGripPoints(AcGePoint3dArray &ar) const { ar.removeAll(); if (GetUsageMode() == eVerti) { /* 垂直剖切 上层 pt0-----------pt1-----------pt2 V V V V V V V V V V pt5-----------pt4-----------pt3 pt1 移动眼睛位置 pt0,pt2 修改视口宽度 pt4 修改 视口的纵深 既 m_vtEye 的长度 pt5,pt3 旋转 m_vtEye 的方向 最后一个 pt10 是输出结果的位置点 下层 pt6-------------------------pt7 V V V V V V V V V V pt9-----------pt10----------pt8 */ AcGeVector3d vtEye(GetEyeDirect()); AcGeVector3d vt(vtEye); vt.rotateBy(PI * .5, AcGeVector3d::kZAxis); vt.normalize(); vt *= GetWidth() * .5; AcGePoint3d ptEye(GetEyePoint()); AcGePoint3d pt1(ptEye), pt0(ptEye - vt), pt2(ptEye + vt); AcGePoint3d pt3 = pt2 + vtEye, pt5 = pt0 + vtEye, pt4 = pt1 + vtEye; pt0.z = pt1.z = pt2.z = pt3.z = pt4.z = pt5.z = GetHorizTop(); ar.append(pt0); ar.append(pt1); ar.append(pt2); ar.append(pt3); ar.append(pt4); ar.append(pt5); AcGePoint3d pt6(pt0), pt7(pt2), pt8(pt3), pt9(pt5), pt10(pt4); pt6.z = pt7.z = pt8.z = pt9.z = pt10.z = GetHorizBottom(); ar.append(pt6); ar.append(pt7); ar.append(pt8); ar.append(pt9); ar.append(pt10); } else if (GetUsageMode() == eHoriz) { /* 水平剖切 上层 pt0-------------------------pt1 | | | | | pt4 | | | | | pt3---------pt9-------------pt2 下层 pt5-------------------------pt6 | | | | | | | | | | pt8---------pt10------------pt7 上层是 pt0 ,pt1, pt2, pt3, pt4(pt0, pt1中点, 既是eye点) 下层是 pt5 ,pt6, pt7, pt8 pt9(pt3, pt2 中点) pt10(pt8, pt7 中点) pt11(输出结果的位置点) 功能: pt0-pt3,改变矩形框大小 当不是水平俯视图的时候 pt9,pt10 改变视口深度 */ AcGePoint3d pt4(GetEyePoint()); double dW(GetWidth()), dH(GetHeight()); AcGePoint3d pt0(pt4); pt0.x -= dW * .5; pt0.y += dH * .5; AcGePoint3d pt1(pt0); pt1.x += dW; AcGePoint3d pt2(pt1); pt2.y -= dH; AcGePoint3d pt3(pt2); pt3.x -= dW; AcGePoint3d pt9(CoreTools::MidPt(pt3, pt2)); pt0.z = pt1.z = pt2.z = pt3.z = pt4.z = pt9.z = GetHorizTop(); AcGePoint3d pt5(pt0), pt6(pt1), pt7(pt2), pt8(pt3), pt10(pt9); pt5.z = pt6.z = pt7.z = pt8.z = pt10.z = GetHorizBottom(); ar.append(pt0); ar.append(pt1); ar.append(pt2); ar.append(pt3); ar.append(pt4); ar.append(pt5); ar.append(pt6); ar.append(pt7); ar.append(pt8); ar.append(pt9); ar.append(pt10); } AcGePoint3d ptLT, ptRT, ptRB, ptLB; if (getResultBox(ptLT, ptRT, ptRB, ptLB)) { ar.append(CoreTools::MidPt(ptLB, ptRB)); } else ar.append(GetOutputPoint()); } AcDbExtents AecDbXCamera::getResultExtent() const { AcDbExtents ext, _ext; for (int i(0); i < m_arResults.length(); ++i) { AcDbEntityPointer ent(m_arResults[i], AcDb::kForRead); if (ent.openStatus() == Acad::eOk) { ent->getGeomExtents(_ext); ext.addExt(_ext); } } return ext; } bool AecDbXCamera::getResultBox(AcGePoint3d &ptLT , AcGePoint3d &ptRT , AcGePoint3d &ptRB , AcGePoint3d &ptLB) const { if (m_arResults.isEmpty()) return false; AcDbExtents ext(getResultExtent()); AcGePoint3d ptIns(CoreTools::MidPt(ext.maxPoint(), ext.minPoint())); double dX(ext.maxPoint().x - ext.minPoint().x) , dY(ext.maxPoint().y - ext.minPoint().y); double dDelta(dX > dY ? dY * .1 : dX * .1); dX += dDelta; dY += dDelta; ptLB = ptIns; ptRB = ptIns; ptLB.x -= dX * .5; ptLB.y -= dY * .5; ptRB.x += dX * .5; ptRB.y -= dY * .5; ptRT = ptRB; ptLT = ptLB; ptRT.y += dY; ptLT.y += dY; return true; } AecDbObjXDataMap *AecDbXCamera::GetSpecialtyData(AcDb::OpenMode bMode) { if (bMode == AcDb::kForWrite) AssertWriteEnabled(); else assertReadEnabled(); return &m_mapSpecXData; } const AecDbObjXDataMap *AecDbXCamera::GetSpecialtyData() const { assertReadEnabled(); return &m_mapSpecXData; } void AecDbXCamera::eraseEnt(AcDbObjectId & id, Adesk::Boolean erasing) { ::eraseEnt(id, erasing); } void AecDbXCamera::eraseEnts(AcDbObjectIdArray & ids, Adesk::Boolean erasing) { for (int i(0); i < ids.length(); ++i) eraseEnt(ids[i]); ids.removeAll(); } resbuf* AecDbXCamera::getSelectTypeResbuf() { // 构筑物单独处理 return acutBuildList( RTDXF0, _T("AEC_*,INSERT") , -4, _T("") , -4, _T("not>") , 0); } void AecDbXCamera::updateSelecttionSet(const AcDbObjectIdArray &ids) { AssertWriteEnabled(); m_arSelectionSet.removeAll(); m_arSelectionSet.append(ids); if (m_arSelectionSet.isEmpty()) return; AcDbExtents ext, _ext; for (int i(0); i < m_arSelectionSet.length(); ++i) { AcDbEntityPointer ent(m_arSelectionSet[i], AcDb::kForRead); if (ent.openStatus() != Acad::eOk) continue; ent->getGeomExtents(_ext); ext.addExt(_ext); } AcGePoint3d ptMax(ext.maxPoint()), ptMin(ext.minPoint()); double dW(ptMax.x - ptMin.x), dH(ptMax.y - ptMin.y); AcGeVector3d vtEye(-AcGeVector3d::kZAxis * (ptMax.z - ptMin.z)); AcGePoint3d ptEye(CoreTools::MidPt(ptMax, ptMin)); SetEyePoint(ptEye); SetEyeDirect(vtEye); SetHorizTop(ptMax.z); SetHorizBottom(ptMin.z); SetWidth(dW); SetHeight(dH); refresh(true); } void AecDbXCamera::collectEnvelope(const AcDbObjectIdArray &arids , AcDbObjectIdArray &arOther , AcDbObjectIdArray &arEnve) { for (int i(0); i < arids.length(); ++i) { const AcDbObjectId &id(arids[i]); if (isEnvelope(id)) arEnve.append(id); else arOther.append(id); } } void AecDbXCamera::collectEnvelope(AcDbObjectIdArray &arids) const { assertReadEnabled(); struct resbuf *pointlist(getCollectArea()); if (pointlist) { struct resbuf *pRb = HlrCutOption::getEnvelopeFilter(); if (pRb) { collectEnities(pRb, pointlist, arids); acutRelRb(pRb); } acutRelRb(pointlist); } } void AecDbXCamera::collectAxisObject(AcDbObjectIdArray &arids) const { assertReadEnabled(); struct resbuf *pointlist(getCollectArea()); struct resbuf *pRb(NULL); if (GetUsageMode() == eHoriz) // 水平 { // 水平,需要 轴号,标注,轴网 pRb = acutBuildList( -4, _T("") , -4, _T("") , -4, _T("") , -4, _T("") , -4, _T("or>") , 0); } else if ((GetUsageMode() == eVerti)) { // 垂直,需要 轴号,轴网 pRb = acutBuildList( -4, _T("") , -4, _T("or>") , 0); } collectEnities(pRb, pointlist, arids); acutRelRb(pRb); acutRelRb(pointlist); } void AecDbXCamera::moveOutput(const AcGeVector3d &vtOffset) { SetOutputPoint(GetOutputPoint() + vtOffset); AcGeMatrix3d mat; mat.setToTranslation(vtOffset); for (int i(0); i < m_arResults.length(); ++i) { AcDbEntityPointer ent(m_arResults[i], AcDb::kForWrite); if (ent.openStatus() == Acad::eOk && !ent->isErased()) ent->transformBy(mat); } } AcDbPolyline* AecDbXCamera::getSectionPolygon() { AcGePoint3d ptEye(GetEyePoint()) , pt1(AcGePoint3d::kOrigin) , pt2(AcGePoint3d::kOrigin) , pt3(AcGePoint3d::kOrigin) , pt4(AcGePoint3d::kOrigin); ptEye.z = .0; AcGeVector3d X(AcGeVector3d::kXAxis), Y(AcGeVector3d::kYAxis), Z(AcGeVector3d::kZAxis); AcGePoint3dArray ar; getGripPoints(ar); AcDbPolyline *pPoly = new AcDbPolyline; if (GetUsageMode() == eVerti && ar.length() > 7) { // 前面应该调用 getEelevRange() 分析出最大最小标高 double dTop(GetHorizTop()), dBottom(GetHorizBottom()); pt1 = ar[0]; pt2 = ar[2]; pt3 = ar[7]; pt4 = ar[6]; AcGeVector3d vecNormal(GetEyeDirect().normal()); AcGeMatrix3d matWcs2Ocs; matWcs2Ocs.setToWorldToPlane(vecNormal); pt1.transformBy(matWcs2Ocs); pt2.transformBy(matWcs2Ocs); pt3.transformBy(matWcs2Ocs); pt4.transformBy(matWcs2Ocs); pPoly->setNormal(vecNormal); pPoly->setElevation(pt1.z); pPoly->addVertexAt(0, AcGePoint2d(pt1.x, pt1.y)); pPoly->addVertexAt(1, AcGePoint2d(pt2.x, pt2.y)); pPoly->addVertexAt(2, AcGePoint2d(pt3.x, pt3.y)); pPoly->addVertexAt(3, AcGePoint2d(pt4.x, pt4.y)); pPoly->setClosed(Adesk::kTrue); } else if (GetUsageMode() == eHoriz) { pt1 = ar[0]; pt2 = ar[1]; pt3 = ar[2]; pt4 = ar[3]; pPoly->setNormal(Z); pPoly->setElevation(.0); pPoly->addVertexAt(0, pt1.convert2d(AcGePlane::kXYPlane)); pPoly->addVertexAt(1, pt2.convert2d(AcGePlane::kXYPlane)); pPoly->addVertexAt(2, pt3.convert2d(AcGePlane::kXYPlane)); pPoly->addVertexAt(3, pt4.convert2d(AcGePlane::kXYPlane)); pPoly->setClosed(Adesk::kTrue); } return pPoly; } bool AecDbXCamera::GetProperties(SimpleProperty::PropertySetByIndex &properties) const { AecDbEntityBase::GetProperties(properties); CoreTools::setLayerPorperty(properties); SimpleProperty::makeAndInsert(properties, _T("剖面上标高"), GetHorizTop(), true); SimpleProperty::makeAndInsert(properties, _T("剖面下标高"), GetHorizBottom(), true); return true; } bool AecDbXCamera::SetProperties(SimpleProperty::PropertySetByName &properties) { if (properties.m_set.empty()) return false; AecDbEntityBase::SetProperties(properties); double dVal(.0); if (properties.findAndSet(_T("剖面上标高"), dVal)) SetHorizTop(dVal); if (properties.findAndSet(_T("剖面下标高"), dVal)) SetHorizBottom(dVal); return true; } #pragma region JIG XCameraJig_V::XCameraJig_V(void): m_pPolyline(NULL) { m_pPolyline = new AcDbPolyline; } XCameraJig_V::~XCameraJig_V(void) { DELETE_PTR(m_pPolyline); } AcEdJig::DragStatus XCameraJig_V::DoIt() { AcEdJig::DragStatus eStat; if (m_nStep == 0) { setDispPrompt(_T("\n指定第二点:")); eStat = drag(); } else if (m_nStep == 1) { setDispPrompt(_T("\n指定剖切范围和方向:")); eStat = drag(); } else { setDispPrompt(_T("\n指定生成结果的位置:")); eStat = drag(); } return eStat; } AcEdJig::DragStatus XCameraJig_V::sampler() { setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted)); m_pPolyline->reset(false, 0); AcEdJig::DragStatus eStat; if (m_nStep == 0) { eStat = acquirePoint(m_ptEnd, m_ptStart); if (eStat == AcEdJig::kNormal) { if (m_ptEnd == m_ptStart) return AcEdJig::kNoChange; m_ptEnd.z = .0; m_ptEye = CoreTools::MidPt(m_ptEnd, m_ptStart); } } else if (m_nStep == 1) { eStat = acquirePoint(m_ptDir, m_ptEye); if (eStat == AcEdJig::kNormal) { if (m_ptDir == m_ptEye) return AcEdJig::kNoChange; m_ptDir.z = .0; AcDbLine line(m_ptStart, m_ptEnd); AcGePoint3d ptClosed; line.getClosestPointTo(m_ptDir, ptClosed, Adesk::kTrue); m_vtEye = m_ptDir - ptClosed; } } else { eStat = acquirePoint(m_ptOutput, m_ptEye); m_ptOutput.z = .0; } return eStat; } AcDbEntity *XCameraJig_V::entity() const { return m_pPolyline; } Adesk::Boolean XCameraJig_V::update() { if (m_nStep >= 0) { double dw = CoreTools::PixelToWcs(10); m_pPolyline->addVertexAt(0, m_ptStart.convert2d(AcGePlane::kXYPlane)); m_pPolyline->addVertexAt(1, m_ptEnd.convert2d(AcGePlane::kXYPlane)); m_pPolyline->setWidthsAt(0, dw, dw); } if (m_nStep >= 1) { AcGePoint3d ptS2(m_ptStart + m_vtEye), ptE2(m_ptEnd + m_vtEye); m_pPolyline->addVertexAt(2, ptE2.convert2d(AcGePlane::kXYPlane)); m_pPolyline->addVertexAt(3, ptS2.convert2d(AcGePlane::kXYPlane)); m_pPolyline->setClosed(Adesk::kTrue); } return Adesk::kTrue; } ///////////////////////////////////////////////////////// XCameraJig_H::XCameraJig_H(void): m_pPolyline(NULL) { m_pPolyline = new AcDbPolyline; } XCameraJig_H::~XCameraJig_H(void) { DELETE_PTR(m_pPolyline); } AcEdJig::DragStatus XCameraJig_H::DoIt() { AcEdJig::DragStatus eStat; if (m_nStep == 0) { setDispPrompt(_T("\n指定切面范围第二点:")); eStat = drag(); } else if (m_nStep == 1) { setDispPrompt(_T("\n指定生成结果的位置:")); eStat = drag(); } return eStat; } AcEdJig::DragStatus XCameraJig_H::sampler() { setUserInputControls((UserInputControls)(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted)); AcEdJig::DragStatus eStat; if (m_nStep == 0) { eStat = acquirePoint(m_ptRB, m_ptLT); if (eStat == AcEdJig::kNormal) { if (m_ptRB == m_ptLT) return AcEdJig::kNoChange; m_ptRB.z = .0; m_ptEye = CoreTools::MidPt(m_ptRB, m_ptLT); m_ptLB = m_ptLT; m_ptLB.y = m_ptRB.y; m_ptRT = m_ptRB; m_ptRT.y = m_ptLT.y; } } else if (m_nStep == 1) { eStat = acquirePoint(m_ptOutput, m_ptEye); m_ptOutput.z = .0; } return eStat; } AcDbEntity *XCameraJig_H::entity() const { return m_pPolyline; } Adesk::Boolean XCameraJig_H::update() { if (m_nStep >= 0) { m_pPolyline->reset(false, 0); double dw = CoreTools::PixelToWcs(10); m_pPolyline->addVertexAt(0, m_ptLT.convert2d(AcGePlane::kXYPlane), .0, dw, dw); m_pPolyline->addVertexAt(1, m_ptRT.convert2d(AcGePlane::kXYPlane), .0, dw, dw); m_pPolyline->addVertexAt(2, m_ptRB.convert2d(AcGePlane::kXYPlane), .0, dw, dw); m_pPolyline->addVertexAt(3, m_ptLB.convert2d(AcGePlane::kXYPlane), .0, dw, dw); m_pPolyline->addVertexAt(4, m_ptLT.convert2d(AcGePlane::kXYPlane), .0, dw, dw); } //if (m_nStep >= 1) //{ // AcGePoint3d ptS2(m_ptStart + m_vtEye), ptE2(m_ptEnd + m_vtEye); // m_pPolyline->addVertexAt(2, ptE2.convert2d(AcGePlane::kXYPlane)); // m_pPolyline->addVertexAt(3, ptS2.convert2d(AcGePlane::kXYPlane)); // m_pPolyline->setClosed(Adesk::kTrue); //} return Adesk::kTrue; } #pragma endregion