This example displays a pyramid, showing the front edges in yellow and the back edges in blue to give you an idea of the visible and hidden edges of the pyramid. The example shows applying the model-to-eye transformation and then the perspective transformation. It uses eye coordinates to draw the entity and shows use of isPerspective(), doPerspective(), getFrontandBackClipValues(), polylineDc(), polylineEye(), and polyline().
If you're using the polygonEye(), polygonDc(), polylineEye(), or polylineDc() functions of AcGiViewportGeometry, you should call AcGiWorldGeometry::setExtents() to establish the bounding box for the entity. This will let AutoCAD know how much space the entity requires and is used in ZOOM Extents. The setExtents() function is usually called when the entity is in world coordinates to determine the smallest box that will fit around the entity in world coordinates.
AsdkViewGeomSamp::AsdkViewGeomSamp() : mNumVerts(4) { mVerts[0] = AcGePoint3d(0.0, 0.0, 0.0); mVerts[1] = AcGePoint3d(1.0, 0.0, 0.0); mVerts[2] = AcGePoint3d(0.0, 1.0, 0.0); mVerts[3] = AcGePoint3d(0.0, 0.0, 1.0); } Acad::ErrorStatus AsdkViewGeomSamp::subTransformBy(const AcGeMatrix3d &xfm) { assertWriteEnabled(); for (Adesk::UInt32 i = 0; i < mNumVerts; i++) { mVerts[i].transformBy(xfm); } return Acad::eOk; } Adesk::Boolean AsdkViewGeomSamp::subWorldDraw(AcGiWorldDraw* pW) { // Draw a pyramid. // If this is the REGULAR ACAD DISPLAY mode, // if (pW->regenType() == kAcGiStandardDisplay) { // from each viewport's vantage point, figure out // which sides of the pyramid are visible, // then draw the visible ones yellow and the hidden // ones blue. // Set the extents of the pyramid here because // AcGiViewportGeometrys polylineEye() doesnt // set extents. // for (Adesk::UInt32 i = 0; i < mNumVerts; i++) { AcGePoint3d pt[2]; pt[0] = mVerts[i]; pt[1] = mVerts[(i + 1) % mNumVerts]; pW->geometry().setExtents(pt); } return Adesk::kFalse; // Call viewport draws. } // Otherwise give HIDE, SHADE, RENDER, or Proxy Graphics // a pyramid with filled faces. // const Adesk::UInt32 faceListSize = 16; static Adesk::Int32 faceList[faceListSize] = { 3, 0, 1, 2, 3, 0, 2, 3, 3, 0, 3, 1, 3, 1, 2, 3 }; pW->geometry().shell(mNumVerts, mVerts, faceListSize, faceList); return Adesk::kTrue; // Do NOT CALL viewportDraw. } void AsdkViewGeomSamp::subViewportDraw(AcGiViewportDraw* pV) { // For this viewport, draw a pyramid with yellow // visible lines and blue hidden lines. // Get this viewport's net transform. This transform // includes this entity's block transforms and this // viewport's view transform; it does not include the // perspective transform if we're in perspective // mode -- that currently has to be applied separately // when in perspective mode. // AcGeMatrix3d modelToEyeMat; pV->viewport().getModelToEyeTransform(modelToEyeMat); // Get the pyramid's vertices. // AcGePoint3d A = mVerts[0]; AcGePoint3d B = mVerts[1]; AcGePoint3d C = mVerts[2]; AcGePoint3d D = mVerts[3]; // Convert them to the viewport's eye coordinates. // A.transformBy(modelToEyeMat); B.transformBy(modelToEyeMat); C.transformBy(modelToEyeMat); D.transformBy(modelToEyeMat); // Save the eye coordinates. // AcGePoint3d AEye = A; AcGePoint3d BEye = B; AcGePoint3d CEye = C; AcGePoint3d DEye = D; // Perform the perspective transform if necessary. // if (pV->viewport().isPerspective()) { pV->viewport().doPerspective(A); pV->viewport().doPerspective(B); pV->viewport().doPerspective(C); pV->viewport().doPerspective(D); } // From that view, figure out which faces are // facing the the viewport and which are not. // int which_faces; which_faces = ((C - A).crossProduct(B - A)).z > 0.0 ? 1 : 0; which_faces |= ((D - A).crossProduct(C - A)).z > 0.0 ? 2 : 0; which_faces |= ((B - A).crossProduct(D - A)).z > 0.0 ? 4 : 0; which_faces |= ((B - D).crossProduct(C - D)).z > 0.0 ? 8 : 0; // Those edges that meet between two faces that are // facing away from the viewport will be hidden edges // so draw them blue; otherwise, they are visible // edges. (This example is incomplete as the test is // indeterminate when the face is edge-on to the // screen -- neither facing away or toward the screen.) // Draw the 6 edges connecting the vertices using eye // coordinate geometry that can be back and front // clipped. AcGePoint3d verts[2]; Adesk::UInt16 color; // AB color = which_faces & 0x5 ? kYellow : kBlue; pV->subEntityTraits().setColor(color); verts[0] = AEye; verts[1] = BEye; pV->geometry().polylineEye(2, verts); // AC color = which_faces & 0x3 ? kYellow : kBlue; pV->subEntityTraits().setColor(color); verts[0] = AEye; verts[1] = CEye; pV->geometry().polylineEye(2, verts); // AD color = which_faces & 0x6 ? kYellow : kBlue; pV->subEntityTraits().setColor(color); verts[0] = AEye; verts[1] = DEye; pV->geometry().polylineEye(2, verts); // CD color = which_faces & 0xa ? kYellow : kBlue; pV->subEntityTraits().setColor(color); verts[0] = CEye; verts[1] = DEye; pV->geometry().polylineEye(2, verts); // DB color = which_faces & 0xc ? kYellow : kBlue; pV->subEntityTraits().setColor(color); verts[0] = DEye; verts[1] = BEye; pV->geometry().polylineEye(2, verts); // BC color = which_faces & 0x9 ? kYellow : kBlue; pV->subEntityTraits().setColor(color); verts[0] = BEye; verts[1] = CEye; pV->geometry().polylineEye(2, verts);