void frgExtractTopologicalEntsFromLinesAlgm::_extract_from_seg(Vertex2dsOnSegment2d &stru) { // - 获取相关的线段(相交、重合) AcDbObjectIdArray ids; _search_related_segs(ids, stru.seg); // - 分为两类进行处理:相交和重叠 // -- 增加起点和终点 rlVertex2d *v = NULL; stru.vertex2ds.insert(std::make_pair(0.0, v)); stru.vertex2ds.insert(std::make_pair(1.0, v)); // -- 处理每一个线段 AcDbEntity *entity = NULL; for (int i = 0; i < ids.length(); i++) { acdbOpenAcDbEntity(entity, ids[i], AcDb::kForRead); if (entity == NULL) continue; if (entity->isA() != AcDbLine::desc()) { entity->close(); continue; } AcDbLine *_line = (AcDbLine *)entity; AcGeLineSeg2d _seg(AcGePoint2d(_line->startPoint().x, _line->startPoint().y), AcGePoint2d(_line->endPoint().x, _line->endPoint().y)); _line->close(); _extract_vertices(stru, _seg); } }
void frgExtractTopologicalEntsFromLinesAlgm::_extract_vertices_from_lines(std::vector<Vertex2dsOnSegment2d> &seg_pnts_pairs, const AcDbObjectIdArray &ids) { AcDbEntity *entity = NULL; acedSetStatusBarProgressMeter(_T("正在提取每根线段上的节点..."), 0, ids.length()); for (int i = 0; i < ids.length(); i++) { acdbOpenAcDbEntity(entity, ids[i], AcDb::kForRead); if (entity == NULL) continue; if (entity->isA() != AcDbLine::desc()) { entity->close(); continue; } AcDbLine *line = (AcDbLine *)entity; Vertex2dsOnSegment2d stru; stru.seg.set(AcGePoint2d(line->startPoint().x, line->startPoint().y), AcGePoint2d(line->endPoint().x, line->endPoint().y)); entity->close(); _extract_from_seg(stru); seg_pnts_pairs.push_back(stru); acedSetStatusBarProgressMeterPos(i); } acedRestoreStatusBar(); }
STDMETHODIMP CComPolygon::put_StartPoint(VARIANT newVal) { try { AcAxPoint3d pt = newVal; AXEntityDocLockNoDbOk(m_objRef.objectId()); Acad::ErrorStatus es; AcAxObjectRefPtr<AsdkPoly> pPoly(&m_objRef,AcDb::kForWrite,Adesk::kTrue); if((es=pPoly.openStatus()) != Acad::eOk) throw es; if ((es=pPoly->setStartPoint(AcGePoint2d(pt.x,pt.y)))!=Acad::eOk) throw es; else Fire_Notification(DISPID_STARTPOINT); } catch(const Acad::ErrorStatus) { return Error(L"Failed to set StartPoint.",IID_IComPolygon,E_FAIL); } catch(const HRESULT hr) { return Error(L"Invalid argument.",IID_IComPolygon,hr); } return S_OK; }
bool frgExtractTopologicalEntsFromLinesAlgm::_is_parallel_between(const rlEdge2d *e1, const rlEdge2d *e2) const { // - 构造第一个线段 rlId vId1 = e1->v1(); rlId vId2 = e1->v2(); rlVertex2d *v1 = _topologies->get<rlVertex2d *>(vId1); rlVertex2d *v2 = _topologies->get<rlVertex2d *>(vId2); if (v1 == NULL || v2 == NULL) { assert(false); return false; } AcGeLineSeg2d seg1(AcGePoint2d(v1->x(), v1->y()), AcGePoint2d(v2->x(), v2->y())); // - 构造第二个线段 vId1 = e2->v1(); vId2 = e2->v2(); v1 = _topologies->get<rlVertex2d *>(vId1); v2 = _topologies->get<rlVertex2d *>(vId2); if (v1 == NULL || v2 == NULL) { assert(false); return false; } AcGeLineSeg2d seg2(AcGePoint2d(v1->x(), v1->y()), AcGePoint2d(v2->x(), v2->y())); // - 判断二者是否平行 if (seg1.isParallelTo(seg2, frgGlobals::Gtol) == Adesk::kTrue) return true; return false; }
AcBr::ErrorStatus faceDump(const AcBrFace& faceEntity) { AcBr::ErrorStatus returnValue = AcBr::eOk; // Verify that AcBr was explicitly and not implicitly loaded, // by testing ObjectARX functions (which are unavailable unless // explicitly loaded) 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 (AcBrErrorStatus)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; } AcGeSurface* surfaceGeometry = NULL; AcGeSurface* nativeGeometry = NULL; // NOTE: ignore unsupported geometry types for now, since we already know // that elliptic cylinders and elliptic cones are rejected by AcGe, but we // can still perform useful evaluations on the external bounded surface. returnValue = getNativeSurface(faceEntity, surfaceGeometry, nativeGeometry); if ((returnValue != AcBr::eOk) && (returnValue != (AcBrErrorStatus)Acad::eInvalidInput)) { acutPrintf(ACRX_T("\n Error in getNativeSurface:")); errorReport(returnValue); delete surfaceGeometry; delete nativeGeometry; return returnValue; } switch (entId) { case(kPlane): { acutPrintf(ACRX_T("\nSurface Type: Plane\n")); AcGePlane* planeGeometry = (AcGePlane*)nativeGeometry; AcGePoint3d pt = planeGeometry->pointOnPlane(); AcGeVector3d normal = planeGeometry->normal(); acutPrintf(ACRX_T("\nSurface Definition Data Begin:\n")); acutPrintf(ACRX_T(" Point on Plane is (")); acutPrintf (ACRX_T("%lf , "), pt.x); acutPrintf (ACRX_T("%lf , "), pt.y); acutPrintf (ACRX_T("%lf "), pt.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Plane normal direction is (")); acutPrintf (ACRX_T("%lf , "), normal.x); acutPrintf (ACRX_T("%lf , "), normal.y); acutPrintf (ACRX_T("%lf "), normal.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T("Surface Definition Data End\n")); break; } case(kSphere): { acutPrintf(ACRX_T("\nSurface Type: Sphere\n")); AcGeSphere* sphereGeometry = (AcGeSphere*)nativeGeometry; AcGePoint3d centre = sphereGeometry->center(); double ang1, ang2, ang3, ang4; sphereGeometry->getAnglesInU(ang1, ang2); sphereGeometry->getAnglesInV(ang3, ang4); AcGePoint3d north = sphereGeometry->northPole(); AcGePoint3d south = sphereGeometry->southPole(); acutPrintf(ACRX_T("\nSurface Definition Data Begin:\n")); acutPrintf(ACRX_T(" Sphere centre is (")); acutPrintf (ACRX_T("%lf , "), centre.x); acutPrintf (ACRX_T("%lf , "), centre.y); acutPrintf (ACRX_T("%lf "), centre.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Sphere radius is %lf\n"), sphereGeometry->radius()); acutPrintf(ACRX_T(" Sphere start angle in U is %lf\n"), ang1); acutPrintf(ACRX_T(" Sphere end angle in U is %lf\n"), ang2); acutPrintf(ACRX_T(" Sphere start angle in V is %lf\n"), ang3); acutPrintf(ACRX_T(" Sphere end angle in V is %lf\n"), ang4); acutPrintf(ACRX_T(" Sphere north pole is (")); acutPrintf (ACRX_T("%lf , "), north.x); acutPrintf (ACRX_T("%lf , "), north.y); acutPrintf (ACRX_T("%lf "), north.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Sphere south pole is (")); acutPrintf (ACRX_T("%lf , "), south.x); acutPrintf (ACRX_T("%lf , "), south.y); acutPrintf (ACRX_T("%lf "), south.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T("Surface Definition Data End\n")); break; } case(kTorus): { acutPrintf(ACRX_T("\nSurface Type: Torus\n")); AcGeTorus* torusGeometry = (AcGeTorus*)nativeGeometry; AcGePoint3d centre = torusGeometry->center(); double ang1, ang2, ang3, ang4; torusGeometry->getAnglesInU(ang1, ang2); torusGeometry->getAnglesInV(ang3, ang4); acutPrintf(ACRX_T("\nSurface Definition Data Begin:\n")); acutPrintf(ACRX_T(" Torus centre is (")); acutPrintf (ACRX_T("%lf , "), centre.x); acutPrintf (ACRX_T("%lf , "), centre.y); acutPrintf (ACRX_T("%lf "), centre.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Torus major radius is %lf\n"), torusGeometry->majorRadius()); acutPrintf(ACRX_T(" Torus minor radius is %lf\n"), torusGeometry->minorRadius()); acutPrintf(ACRX_T(" Torus start angle in U is %lf\n"), ang1); acutPrintf(ACRX_T(" Torus end angle in U is %lf\n"), ang2); acutPrintf(ACRX_T(" Torus start angle in V is %lf\n"), ang3); acutPrintf(ACRX_T(" Torus end angle in V is %lf\n"), ang4); acutPrintf(ACRX_T("Surface Definition Data End\n")); break; } case(kCylinder): { acutPrintf(ACRX_T("\nSurface Type: Circular Cylinder\n")); AcGeCylinder* cylinderGeometry = (AcGeCylinder*)nativeGeometry; AcGePoint3d origin = cylinderGeometry->origin(); double ang1, ang2; cylinderGeometry->getAngles(ang1, ang2); AcGeInterval ht; cylinderGeometry->getHeight(ht); double height = ht.upperBound() - ht.lowerBound(); AcGeVector3d refAxis = cylinderGeometry->refAxis(); AcGeVector3d symAxis = cylinderGeometry->axisOfSymmetry(); acutPrintf(ACRX_T("\nSurface Definition Data Begin:\n")); acutPrintf(ACRX_T(" Circular Cylinder origin is (")); acutPrintf (ACRX_T("%lf , "), origin.x); acutPrintf (ACRX_T("%lf , "), origin.y); acutPrintf (ACRX_T("%lf "), origin.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Circular Cylinder radius is %lf\n"), cylinderGeometry->radius()); acutPrintf(ACRX_T(" Circular Cylinder start angle is %lf\n"), ang1); acutPrintf(ACRX_T(" Circular Cylinder end angle is %lf\n"), ang2); if (cylinderGeometry->isClosedInU()) acutPrintf(ACRX_T(" Circular Cylinder height is %lf\n"), height); else acutPrintf(ACRX_T(" Circular Cylinder is not closed in U\n")); acutPrintf(ACRX_T(" Circular Cylinder reference axis is (")); acutPrintf (ACRX_T("%lf , "), refAxis.x); acutPrintf (ACRX_T("%lf , "), refAxis.y); acutPrintf (ACRX_T("%lf "), refAxis.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Circular Cylinder axis of symmetry is (")); acutPrintf (ACRX_T("%lf , "), symAxis.x); acutPrintf (ACRX_T("%lf , "), symAxis.y); acutPrintf (ACRX_T("%lf "), symAxis.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T("Surface Definition Data End\n")); break; } case(kCone): { acutPrintf(ACRX_T("\nSurface Type: Circular Cone\n")); AcGeCone* coneGeometry = (AcGeCone*)nativeGeometry; AcGePoint3d centre = coneGeometry->baseCenter(); double ang1, ang2; coneGeometry->getAngles(ang1, ang2); AcGeVector3d axis1 = coneGeometry->axisOfSymmetry(); AcGeVector3d axis2 = coneGeometry->refAxis(); AcGePoint3d apex = coneGeometry->apex(); double cosAng, sinAng; coneGeometry->getHalfAngle(cosAng, sinAng); AcGeInterval ht; coneGeometry->getHeight(ht); double height = ht.upperBound() - ht.lowerBound(); acutPrintf(ACRX_T("\nSurface Definition Data Begin:\n")); acutPrintf(ACRX_T(" Circular Cone base centre is (")); acutPrintf (ACRX_T("%lf , "), centre.x); acutPrintf (ACRX_T("%lf , "), centre.y); acutPrintf (ACRX_T("%lf "), centre.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Circular Cone base radius is %lf\n"), coneGeometry->baseRadius()); acutPrintf(ACRX_T(" Circular Cone start angle is %lf\n"), ang1); acutPrintf(ACRX_T(" Circular Cone end angle is %lf\n"), ang2); acutPrintf(ACRX_T(" Circular Cone axis of symmetry is (")); acutPrintf (ACRX_T("%lf , "), axis1.x); acutPrintf (ACRX_T("%lf , "), axis1.y); acutPrintf (ACRX_T("%lf "), axis1.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Circular Cone reference axis is (")); acutPrintf (ACRX_T("%lf , "), axis2.x); acutPrintf (ACRX_T("%lf , "), axis2.y); acutPrintf (ACRX_T("%lf "), axis2.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Circular Cone apex is (")); acutPrintf (ACRX_T("%lf , "), apex.x); acutPrintf (ACRX_T("%lf , "), apex.y); acutPrintf (ACRX_T("%lf "), apex.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Circular Cone cosine of major half-angle is %lf\n"), cosAng); acutPrintf(ACRX_T(" Circular Cone sine of major half-angle is %lf\n"), sinAng); if (coneGeometry->isClosedInU()) acutPrintf(ACRX_T(" Circular Cone height is %lf\n"), height); else acutPrintf(ACRX_T(" Circular Cone is not closed in U\n")); acutPrintf(ACRX_T("Surface Definition Data End\n")); break; } case(kNurbSurface): { acutPrintf(ACRX_T("\nSurface Type: NURB Surface\n")); AcGeNurbSurface* nurbGeometry = (AcGeNurbSurface*)nativeGeometry; int nCtrlPtsU = nurbGeometry->numControlPointsInU(); int nCtrlPtsV = nurbGeometry->numControlPointsInV(); int nKnotsU = nurbGeometry->numKnotsInU(); int nKnotsV = nurbGeometry->numKnotsInV(); acutPrintf(ACRX_T("\nSurface Definition Data Begin:\n")); acutPrintf(ACRX_T(" NURB Surface degree in U is %d\n"), nurbGeometry->degreeInU()); acutPrintf(ACRX_T(" NURB Surface degree in V is %d\n"), nurbGeometry->degreeInV()); acutPrintf(ACRX_T(" NURB Surface number of control points in U is %d\n"), nCtrlPtsU); acutPrintf(ACRX_T(" NURB Surface number of control points in V is %d\n"), nCtrlPtsV); acutPrintf(ACRX_T(" NURB Surface number of knots in U is %d\n"), nKnotsU); acutPrintf(ACRX_T(" NURB Surface number of knots in V is %d\n"), nKnotsV); acutPrintf(ACRX_T("Surface Definition Data End\n")); break; } // NOTE: This surface is not yet supported in AcGe, so we infer the definition // data by analysing evaluated data on the external bounded surface. case(kEllipCylinder): { acutPrintf(ACRX_T("\nSurface Type: Elliptic Cylinder\n")); AcGePoint3d p0 = surfaceGeometry->evalPoint(AcGePoint2d(0.0, 0.0)); AcGePoint3d p1 = surfaceGeometry->evalPoint(AcGePoint2d(0.0, kPi)); AcGePoint3d p2 = surfaceGeometry->evalPoint(AcGePoint2d(0.0, kHalfPi)); AcGePoint3d origin(((p0.x + p1.x) / 2.0), ((p0.y + p1.y) / 2.0), ((p0.z + p1.z) / 2.0)); AcGeVector3d majAxis = p0 - origin; AcGeVector3d minAxis = p2 - origin; AcGeVector3d symAxis = (majAxis.crossProduct(minAxis)).normalize(); acutPrintf(ACRX_T("\nSurface Definition Data Begin:\n")); acutPrintf(ACRX_T(" Elliptic Cylinder origin is (")); acutPrintf (ACRX_T("%lf , "), origin.x); acutPrintf (ACRX_T("%lf , "), origin.y); acutPrintf (ACRX_T("%lf "), origin.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Elliptic Cylinder major radius is %lf\n"), majAxis.length()); acutPrintf(ACRX_T(" Elliptic Cylinder minor radius is %lf\n"), minAxis.length()); acutPrintf(ACRX_T(" Elliptic Cylinder major axis is (")); acutPrintf (ACRX_T("%lf , "), majAxis.x); acutPrintf (ACRX_T("%lf , "), majAxis.y); acutPrintf (ACRX_T("%lf "), majAxis.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Elliptic Cylinder minor axis is (")); acutPrintf (ACRX_T("%lf , "), minAxis.x); acutPrintf (ACRX_T("%lf , "), minAxis.y); acutPrintf (ACRX_T("%lf "), minAxis.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Elliptic Cylinder axis of symmetry is (")); acutPrintf (ACRX_T("%lf , "), symAxis.x); acutPrintf (ACRX_T("%lf , "), symAxis.y); acutPrintf (ACRX_T("%lf "), symAxis.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T("Surface Definition Data End\n")); break; } // NOTE: This surface is not yet supported in AcGe, so we infer the definition // data by analysing evaluated data on the external bounded surface. case(kEllipCone): { acutPrintf(ACRX_T("\nSurface Type: Elliptic Cone\n")); AcGePoint3d p0 = surfaceGeometry->evalPoint(AcGePoint2d(0.0, 0.0)); AcGePoint3d p1 = surfaceGeometry->evalPoint(AcGePoint2d(0.0, kPi)); AcGePoint3d p2 = surfaceGeometry->evalPoint(AcGePoint2d(0.0, kHalfPi)); AcGePoint3d p3 = surfaceGeometry->evalPoint(AcGePoint2d(1.0, 0.0)); AcGePoint3d centre(((p0.x + p1.x) / 2.0), ((p0.y + p1.y) / 2.0), ((p0.z + p1.z) / 2.0)); AcGeVector3d majAxis = p0 - centre; AcGeVector3d minAxis = p2 - centre; AcGeVector3d symAxis = (majAxis.crossProduct(minAxis)).normalize(); double halfAng = kHalfPi - majAxis.angleTo(p3 - p0); acutPrintf(ACRX_T("\nSurface Definition Data Begin:\n")); acutPrintf(ACRX_T(" Elliptic Cone base centre is (")); acutPrintf (ACRX_T("%lf , "), centre.x); acutPrintf (ACRX_T("%lf , "), centre.y); acutPrintf (ACRX_T("%lf "), centre.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Elliptic Cone base major radius is %lf\n"), majAxis.length()); acutPrintf(ACRX_T(" Elliptic Cone base minor radius is %lf\n"), minAxis.length()); acutPrintf(ACRX_T(" Elliptic Cone major axis is (")); acutPrintf (ACRX_T("%lf , "), majAxis.x); acutPrintf (ACRX_T("%lf , "), majAxis.y); acutPrintf (ACRX_T("%lf "), majAxis.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Elliptic Cone minor axis is (")); acutPrintf (ACRX_T("%lf , "), minAxis.x); acutPrintf (ACRX_T("%lf , "), minAxis.y); acutPrintf (ACRX_T("%lf "), minAxis.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Elliptic Cone axis of symmetry is (")); acutPrintf (ACRX_T("%lf , "), symAxis.x); acutPrintf (ACRX_T("%lf , "), symAxis.y); acutPrintf (ACRX_T("%lf "), symAxis.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Elliptic Cone cosine of major half-angle is %lf\n"), cos(halfAng)); acutPrintf(ACRX_T(" Elliptic Cone sine of major half-angle is %lf\n"), sin(halfAng)); acutPrintf(ACRX_T("Surface Definition Data End\n")); break; } default: acutPrintf(ACRX_T("\nSurface Type: Unexpected Non Surface\n")); return (AcBrErrorStatus)Acad::eInvalidInput; } // end switch(entId) delete nativeGeometry; // Evaluate the surface - note that the u,v bounds will not consider any // holes in the surface. To compute a u,v zone of exclusion for evaluation, // check for additional (i.e., inner) loops and get the bounding boxes for // the loops, then convert those to parameter space boxes. There is no // particular guarantee that outer loop(s) are the first in the face-loop // list, however, and we currently have no way to query a loop to find out // which type it is. Still, the maximal u,v parameter range will be useful // for most surfaces and most evaluation purposes. AcGeInterval uParam; AcGeInterval vParam; ((AcGeExternalBoundedSurface*)surfaceGeometry)->getEnvelope(uParam, vParam); // Make sure the u,v values are legal and the envelope is bounded if ((uParam.isBounded()) && (vParam.isBounded())) { AcGePoint2d midRange; midRange.x = uParam.lowerBound() + (uParam.length() / 2.0); midRange.y = vParam.lowerBound() + (vParam.length() / 2.0); AcGePoint3d pointOnSurface = ((AcGeExternalBoundedSurface*)surfaceGeometry)->evalPoint(midRange); acutPrintf(ACRX_T("\nSurface Evaluation Begin:\n")); acutPrintf(ACRX_T(" Parameter space bounds are ((")); acutPrintf(ACRX_T("%lf, "), uParam.lowerBound()); acutPrintf(ACRX_T("%lf "), uParam.upperBound()); acutPrintf(ACRX_T("), (\n")); acutPrintf(ACRX_T("%lf, "), vParam.lowerBound()); acutPrintf(ACRX_T("%lf "), vParam.upperBound()); acutPrintf(ACRX_T("))\n")); acutPrintf(ACRX_T(" Parameter space mid-range is (")); acutPrintf(ACRX_T(" %lf, "), midRange.x); acutPrintf(ACRX_T("%lf "), midRange.y); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T(" Point on surface is (")); acutPrintf (ACRX_T("%lf , "), pointOnSurface.x); acutPrintf (ACRX_T("%lf , "), pointOnSurface.y); acutPrintf (ACRX_T("%lf "), pointOnSurface.z); acutPrintf(ACRX_T(")\n")); acutPrintf(ACRX_T("Surface Evaluation End\n")); } 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")); return returnValue; }
void createInsert() { // Create a nested insert and try highlighting its // various subcomponents. // // There are six entities in total -- three polys and // three boxes (solids). We,ve named them: poly1, poly2, // poly3, and box1, box2, box3. We also have three // inserts: ins1, ins2, ins3. // // ins3 is insert of a block that contains (poly3, box3) // ins2 is insert of a block that contains (poly2, box2, // ins3). // ins1 is insert of a block that contains (poly1, box1, // ins2). // // Let's create these entities first. // // Polys // AsdkPoly *poly1, *poly2, *poly3; AcGeVector3d norm(0, 0, 1); if ((poly1=new AsdkPoly)==NULL){ ads_printf("\nOut of Memory."); return; } if (poly1->set(AcGePoint2d(2, 8),AcGePoint2d(4, 8), 6, norm, "POLY1",0)!=Acad::eOk){ ads_printf("\nCannot create object with given parameters."); delete poly1; return; } if ((poly2=new AsdkPoly)==NULL){ ads_printf("\nOut of Memory."); delete poly1; return; } if (poly2->set(AcGePoint2d(7, 8), AcGePoint2d(9, 8), 6, norm, "POLY2",0)!=Acad::eOk){ ads_printf("\nCannot create object with given parameters."); delete poly1; delete poly2; return; } if ((poly3=new AsdkPoly)==NULL){ ads_printf("\nOut of Memory."); delete poly1; delete poly2; return; } if (poly3->set(AcGePoint2d(12, 8),AcGePoint2d(14, 8), 6, norm, "POLY3",0)!=Acad::eOk){ ads_printf("\nCannot create object with given parameters."); delete poly1; delete poly2; delete poly3; return; } postToDb(poly1); postToDb(poly2); postToDb(poly3); // Boxes // AcDb3dSolid *box1, *box2, *box3; box1 = new AcDb3dSolid(); box2 = new AcDb3dSolid(); box3 = new AcDb3dSolid(); box1->createBox(2, 2, 2); box2->createBox(2, 2, 2); box3->createBox(2, 2, 2); AcGeMatrix3d mat; mat(0, 3) = 2; mat(1, 3) = 2; box1->transformBy(mat); mat(0, 3) = 7; mat(1, 3) = 2; box2->transformBy(mat); mat(0, 3) = 12; mat(1, 3) = 2; box3->transformBy(mat); postToDb(box1); postToDb(box2); postToDb(box3); // Inserts // // Arguments to BLOCK are: // blockname, // insert point, // select objects, // empty string for selection complete // Arguments to INSERT are: // blockname, // insertion point, // xscale, // yscale, // rotation angle // ads_command(RTSTR, "_globcheck", RTSHORT, 0, RTNONE); ads_command(RTSTR, "BLOCK", RTSTR, "blk3", RTSTR, "0,0", RTSTR, "14,8", RTSTR, "11,1", RTSTR, "", RTNONE); ads_command(RTSTR, "INSERT", RTSTR, "blk3", RTSTR, "0,0", RTSHORT, 1, RTSHORT, 1, RTSHORT, 0, RTNONE); ads_command(RTSTR, "BLOCK", RTSTR, "blk2", RTSTR, "0,0", RTSTR, "9,8", RTSTR, "6,1", RTSTR, "11,1", RTSTR, "", RTNONE); ads_command(RTSTR, "INSERT", RTSTR, "blk2", RTSTR, "0,0", RTSHORT, 1, RTSHORT, 1, RTSHORT, 0, RTNONE); ads_command(RTSTR, "BLOCK", RTSTR, "blk1", RTSTR, "0,0", RTSTR, "4,8", RTSTR, "1,1", RTSTR, "6,1", RTSTR, "", RTNONE); ads_command(RTSTR, "INSERT", RTSTR, "blk1", RTSTR, "0,0", RTSHORT, 1, RTSHORT, 1, RTSHORT, 0, RTNONE); return; }
//----------------------------------------------------------------------------- // This function is called to update the entity based on the // input values // Adesk::Boolean AsdkRectangleJig::update() { AcGePoint2d adjustedPoint; AcGePoint3d tmpPoint; // Used by MAKEUCSCOORD macro. // We'll use the AcGeLine::intersectWith() function to infer the // remaining points. // AcGeLine3d lineX, lineY; lineX.set(m_TopLeftCorner, m_vecUnitX); lineY.set(m_BottomRightCorner, m_vecUnitY); // Top right corner is intersection of lineX and lineY. // lineX.intersectWith(lineY, m_TopRightCorner); lineX.set(m_BottomRightCorner, m_vecUnitX); lineY.set(m_TopLeftCorner, m_vecUnitY); // Bottom left corner is intersection of lineX and lineY. // lineX.intersectWith(lineY, m_BottomLeftCorner); AcGeVector3d tmpXVec, tmpYVec; // Check to see if we have flipped around the X or Y axis. // bool bXFlip = m_vecUnitX.dotProduct(m_TopLeftCorner - m_TopRightCorner) >0; bool bYFlip = m_vecUnitY.dotProduct(m_TopLeftCorner - m_BottomLeftCorner)<0; // If the rectangle is dragged into the first or third quadrant, // we need to reverse the sign of the bulge as well as reverse // the x and y direction vectors. // tmpXVec = bXFlip ? -1 * m_vecUnitX : m_vecUnitX; tmpYVec = bYFlip ? -1 * m_vecUnitY : m_vecUnitY; // Now update the polyline with the latest setting // if (plineInfo.m_cornerTreatment) { // We are going to fillet of chamfer this polyline rectangle. As such, // the constructor has added the extra points at the corners to allow // for there placement and bulge values to be updated on the fly. // If, during the dragging, the rectangle is still too small to show the // given radius or chamfer edges, the we will put the extra points in the // corners and set the bulges to 0.0, so the rectangle retains its // square corners until the user stretches the rectangle to a size large // enough to have the corner treatment displayed. // // Use temporaries to see if we're too small to show fillet/chamfer, so // we don't need to convert back to world. // AcGePoint2d point_TL, point_TR, point_BL; MAKEUCSCOORD(point_TL, m_TopLeftCorner); MAKEUCSCOORD(point_TR, m_TopRightCorner); MAKEUCSCOORD(point_BL, m_BottomLeftCorner); bool tooSmall = (point_TL.distanceTo(point_TR) < plineInfo.m_first + plineInfo.m_second) || (point_TL.distanceTo(point_BL) < plineInfo.m_first + plineInfo.m_second); if (tooSmall) { // Still to small to show the corner treatment. // m_pLWPoly->setBulgeAt(0, 0.0); MAKEUCSCOORD(adjustedPoint, m_TopLeftCorner); m_pLWPoly->setPointAt(0, adjustedPoint); m_pLWPoly->setPointAt(1, adjustedPoint); m_pLWPoly->setBulgeAt(2, 0.0); MAKEUCSCOORD(adjustedPoint, m_TopRightCorner); m_pLWPoly->setPointAt(2, adjustedPoint); m_pLWPoly->setPointAt(3, adjustedPoint); m_pLWPoly->setBulgeAt(4, 0.0); MAKEUCSCOORD(adjustedPoint, m_BottomRightCorner); m_pLWPoly->setPointAt(4, adjustedPoint); m_pLWPoly->setPointAt(5, adjustedPoint); m_pLWPoly->setBulgeAt(6, 0.0); MAKEUCSCOORD(adjustedPoint, m_BottomLeftCorner); m_pLWPoly->setPointAt(6, adjustedPoint); m_pLWPoly->setPointAt(7, adjustedPoint); } else { double tmpBulge; tmpBulge = ((!bXFlip && !bYFlip) || (bXFlip && bYFlip)) ? plineInfo.m_bulge : -plineInfo.m_bulge; // Now we will set adjustedPoint to the intersection of the rectangle // sides with the place where the new end points will be. // m_pLWPoly->setBulgeAt(0, tmpBulge); MAKEUCSCOORD(adjustedPoint, m_TopLeftCorner + (-plineInfo.m_first * tmpYVec)); m_pLWPoly->setPointAt(0, adjustedPoint); MAKEUCSCOORD(adjustedPoint, m_TopLeftCorner + plineInfo.m_second * tmpXVec); m_pLWPoly->setPointAt(1, adjustedPoint); m_pLWPoly->setBulgeAt(2, tmpBulge); MAKEUCSCOORD(adjustedPoint, m_TopRightCorner + (-plineInfo.m_first * tmpXVec)); m_pLWPoly->setPointAt(2, adjustedPoint); MAKEUCSCOORD(adjustedPoint, m_TopRightCorner + (-plineInfo.m_second * tmpYVec)); m_pLWPoly->setPointAt(3, adjustedPoint); m_pLWPoly->setBulgeAt(4, tmpBulge); MAKEUCSCOORD(adjustedPoint, m_BottomRightCorner + plineInfo.m_first * tmpYVec); m_pLWPoly->setPointAt(4, adjustedPoint); MAKEUCSCOORD(adjustedPoint, m_BottomRightCorner + (-plineInfo.m_second * tmpXVec)); m_pLWPoly->setPointAt(5, adjustedPoint); m_pLWPoly->setBulgeAt(6, tmpBulge); MAKEUCSCOORD(adjustedPoint, m_BottomLeftCorner + plineInfo.m_first * tmpXVec); m_pLWPoly->setPointAt(6, adjustedPoint); MAKEUCSCOORD(adjustedPoint, m_BottomLeftCorner + plineInfo.m_second * tmpYVec); m_pLWPoly->setPointAt(7, AcGePoint2d(adjustedPoint[X], adjustedPoint[Y])); } } else { // If this polyline is not having its corners treated, ie chamfered, or // filleted then simply update the corners. Since we knew this ahead of // time, the constructor did not add any extra verticies at the corners. // MAKEUCSCOORD(adjustedPoint, m_TopLeftCorner); m_pLWPoly->setPointAt(0, adjustedPoint); MAKEUCSCOORD(adjustedPoint, m_TopRightCorner); m_pLWPoly->setPointAt(1, adjustedPoint); MAKEUCSCOORD(adjustedPoint, m_BottomRightCorner); m_pLWPoly->setPointAt(2, adjustedPoint); MAKEUCSCOORD(adjustedPoint, m_BottomLeftCorner); m_pLWPoly->setPointAt(3, adjustedPoint); } return Adesk::kTrue; }
//----------------------------------------------------------------------------- // Constructor that accepts a reference to a CRectInfo class which // contains all the information need to initialize the polyline entitiy // that will be used for dragging and ultimately be the polyline that // gets to the database if all goes well. // AsdkRectangleJig::AsdkRectangleJig() { m_pLWPoly = new AcDbPolyline(); samplerCorner = AcGePoint3d(); plineInfo.m_cornerTreatment = plineInfo.m_first != 0.0 || plineInfo.m_second != 0.0 || plineInfo.m_radius != 0.0; // Now need to get the current UCS Z-Axis to be used as the normal vector // for the rectangle. At the same time, we get the x and y unit direction // vectors used later. // if(inPaperSpace()) { m_vecUnitX = acdbHostApplicationServices()->workingDatabase()->pucsxdir(); m_vecUnitY = acdbHostApplicationServices()->workingDatabase()->pucsydir(); } else { m_vecUnitX = acdbHostApplicationServices()->workingDatabase()->ucsxdir(); m_vecUnitY = acdbHostApplicationServices()->workingDatabase()->ucsydir(); } m_vecUnitZ = m_vecUnitX.crossProduct(m_vecUnitY); // Convert the incomming UCS point to ECS coordinate system // acdbUcs2Ecs(asDblArray(plineInfo.m_topLeftCorner), asDblArray(m_TopLeftCorner), asDblArray(m_vecUnitZ), Adesk::kFalse); acdbUcs2Ecs(asDblArray(plineInfo.m_topLeftCorner), asDblArray(plineInfo.m_topLeftCorner), asDblArray(m_vecUnitZ), Adesk::kFalse); AcGePoint2d initPoint; initPoint = AcGePoint2d(m_TopLeftCorner[X], m_TopLeftCorner[Y]); // If the user has set the elev option from the main command prompt, // then this will be the default until the user again sets it to 0.0. // If however the user simply picks a point with or without an object // snap, then use the Z value of the first point picked. // if (plineInfo.m_elevHandSet == TRUE) m_pLWPoly->setElevation(plineInfo.m_elev); else m_pLWPoly->setElevation(m_TopLeftCorner[Z]); // If we are indeed filleting or chamfering the corners, then // we'll add the extra verticies here to have their bulges and // distances from the real corner changed on the fly. // if (plineInfo.m_cornerTreatment == TRUE) { for (int i = 0 ; i < 8; i++) m_pLWPoly->addVertexAt(i, initPoint); } else { for (int i = 0 ; i < 4; i++) m_pLWPoly->addVertexAt(i, initPoint); } m_pLWPoly->setNormal(m_vecUnitZ); m_pLWPoly->setClosed(Adesk::kTrue); m_pLWPoly->setThickness(plineInfo.m_thick); m_pLWPoly->setConstantWidth(plineInfo.m_width); // Get the current default linetype scale m_pLWPoly->setLinetypeScale(acdbHostApplicationServices() ->workingDatabase()->celtscale()); // Now for jig dragger purposes, convert the point back to world // coordinates. // acdbEcs2Wcs(asDblArray(m_TopLeftCorner), asDblArray(m_TopLeftCorner), asDblArray(m_vecUnitZ), Adesk::kFalse); acdbEcs2Wcs(asDblArray(plineInfo.m_topLeftCorner), asDblArray(plineInfo.m_topLeftCorner), asDblArray(m_vecUnitZ), Adesk::kFalse); }
AcGePoint2d Point3D_To_2D( const AcGePoint3d& pt ) { return AcGePoint2d( pt.x, pt.y ); }