diff options
Diffstat (limited to 'Master/CGuCAD/projects/Prakt5Greedy/Prakt5Greedy/acrxEntryPoint.cpp')
| -rw-r--r-- | Master/CGuCAD/projects/Prakt5Greedy/Prakt5Greedy/acrxEntryPoint.cpp | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/Master/CGuCAD/projects/Prakt5Greedy/Prakt5Greedy/acrxEntryPoint.cpp b/Master/CGuCAD/projects/Prakt5Greedy/Prakt5Greedy/acrxEntryPoint.cpp new file mode 100644 index 0000000..9983595 --- /dev/null +++ b/Master/CGuCAD/projects/Prakt5Greedy/Prakt5Greedy/acrxEntryPoint.cpp @@ -0,0 +1,409 @@ +// (C) Copyright 2002-2007 by Autodesk, Inc.
+//
+// Permission to use, copy, modify, and distribute this software in
+// object code form for any purpose and without fee is hereby granted,
+// provided that the above copyright notice appears in all copies and
+// that both that copyright notice and the limited warranty and
+// restricted rights notice below appear in all supporting
+// documentation.
+//
+// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
+// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
+// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
+// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
+// UNINTERRUPTED OR ERROR FREE.
+//
+// Use, duplication, or disclosure by the U.S. Government is subject to
+// restrictions set forth in FAR 52.227-19 (Commercial Computer
+// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
+// (Rights in Technical Data and Computer Software), as applicable.
+//
+
+//-----------------------------------------------------------------------------
+//----- acrxEntryPoint.cpp
+//-----------------------------------------------------------------------------
+#include "StdAfx.h"
+#include "resource.h"
+#include <vector>
+#include <list>
+#include "Utils.h"
+
+//-----------------------------------------------------------------------------
+#define szRDS _RXST("CGCAD_sei")
+
+// Global
+#define TRIANG_LAYER _T("TRIANG")
+
+//-----------------------------------------------------------------------------
+//----- ObjectARX EntryPoint
+class CPrakt5GreedyApp : public AcRxArxApp {
+
+public:
+ CPrakt5GreedyApp () : AcRxArxApp () {}
+
+ virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
+ // TODO: Load dependencies here
+
+ // You *must* call On_kInitAppMsg here
+ AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
+
+ // TODO: Add your initialization code here
+
+ return (retCode) ;
+ }
+
+ virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
+ // TODO: Add your code here
+
+ // You *must* call On_kUnloadAppMsg here
+ AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
+
+ // TODO: Unload dependencies here
+
+ return (retCode) ;
+ }
+
+ virtual void RegisterServerComponents () {
+ }
+
+
+ // - CGCAD_seiPrakt5Greedy._Greedy command (do not rename)
+ static void CGCAD_seiPrakt5Greedy_Greedy(void)
+ {
+ AcDbPolyline* pPolyline = NULL;
+
+ acdbTransactionManager->startTransaction();
+ int res = selectPolyline(pPolyline);
+ if(res != RTNORM) {
+ acutPrintf(_T("\nError selecting polyline"));
+ acdbTransactionManager->abortTransaction();
+ return;
+ } else {
+ acutPrintf(_T("\nPolyline has %d Vertices"),pPolyline->numVerts());
+ }
+ res = createTriangLayer();
+ if(res != RTNORM) {
+ acutPrintf(_T("\nError creating TRIANG layer"));
+ acdbTransactionManager->abortTransaction();
+ return;
+ }
+ res = Greedy(pPolyline);
+ if(res != RTNORM) {
+ acutPrintf(_T("\nError in Greedy"));
+ acdbTransactionManager->abortTransaction();
+ return;
+ }
+ acdbTransactionManager->endTransaction();
+ }
+ static int selectPolyline(AcDbPolyline *&pPolyline) {
+ ads_name objName;
+ AcDbEntity* pEnt = NULL;
+ AcDbObjectId objId = AcDbObjectId::kNull;
+ int res = RTNORM;
+ ads_point pickPoint;
+ res = acedEntSel(_T("\nPlease select polyline"),objName,pickPoint);
+
+ if (res != RTNORM) {
+ acutPrintf(_T("\nError selecting entity"));
+ return res;
+ }
+ if (Acad::eOk != acdbGetObjectId(objId,objName)) {
+ acutPrintf(_T("\nCould not fetch objid for face"));
+ res = -1;
+ return res;
+ }
+ if (acdbTransactionManager->getObject((AcDbObject*&)pEnt,objId,AcDb::kForRead) != Acad::eOk) {
+ acutPrintf(_T("\nCould not get Object"));
+ res = -1;
+ return res;
+ }
+ if ( pEnt->isKindOf(AcDbPolyline::desc()) ) {
+ acutPrintf(_T("\nObject is a Polyline"));
+ pPolyline = AcDbPolyline::cast(pEnt);
+ }
+ return res;
+ }
+ static int addObject(AcDbEntity*& pEnt) {
+ AcDbBlockTable* pBlockTable = NULL;
+ AcDbObjectId newObjId = AcDbObjectId::kNull;
+ AcDbBlockTableRecord* pBlockTableRecord = NULL;
+ Acad::ErrorStatus res = acdbTransactionManager->getObject((AcDbObject*&) pBlockTable,curDoc()->database()->blockTableId(),AcDb::kForRead);
+ if (res != Acad::eOk) {
+ acdbTransactionManager->abortTransaction();
+ acutPrintf(_T("\nError opening Block Table. Exiting"));
+ return -1;
+ }
+ if( Acad::eOk != pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForRead) ) {
+ acdbTransactionManager->abortTransaction();
+ pBlockTableRecord->close();
+ acutPrintf(_T("\nError opening Block Table Record. Exiting"));
+ return -1;
+ }
+ if (Acad::eOk != pBlockTableRecord->upgradeOpen() ) {
+ acdbTransactionManager->abortTransaction();
+ pBlockTableRecord->close();
+ acutPrintf(_T("\nError opening Block Table Record for write. Exiting"));
+ return -1;
+ }
+ if ( Acad::eOk != pBlockTableRecord->appendAcDbEntity(newObjId, pEnt)) {
+ acdbTransactionManager->abortTransaction();
+ pBlockTableRecord->close();
+ acutPrintf(_T("\nError adding entity to Block Table Record. Exiting"));
+ return -1;
+ }
+ if (Acad::eOk != pBlockTableRecord->downgradeOpen() ) {
+ acdbTransactionManager->abortTransaction();
+ pBlockTableRecord->close();
+ acutPrintf(_T("\nError downgrading Block Table Record for read. Exiting"));
+ return -1;
+ }
+
+ if ( Acad::eOk != acdbTransactionManager->addNewlyCreatedDBRObject(pEnt) ) {
+ acdbTransactionManager->abortTransaction();
+ pBlockTableRecord->close();
+ acutPrintf(_T("\nError adding new entity to TransactionManager. Exiting"));
+ return -1;
+ }
+ pBlockTableRecord->close();
+ return 0;
+ }
+ static int createTriangLayer() {
+ AcDbLayerTable *pLayerTable = NULL;
+
+ acdbTransactionManager->startTransaction();
+ Acad::ErrorStatus res = acdbTransactionManager->getObject((AcDbObject*&) pLayerTable,curDoc()->database()->layerTableId(),AcDb::kForRead);
+
+ AcDbLayerTableRecord *pTriangLayerTableRecord = NULL;
+
+ if (!pLayerTable->has(TRIANG_LAYER)) {
+ acutPrintf(_T("\nCreating TRIANG Layer"));
+ pLayerTable->upgradeOpen();
+ pTriangLayerTableRecord = new AcDbLayerTableRecord;
+ pTriangLayerTableRecord->setName(TRIANG_LAYER);
+ AcCmColor polyColor;
+ polyColor.setRGB(0,0,255);
+ pTriangLayerTableRecord->setColor(polyColor);
+ pTriangLayerTableRecord->setIsLocked(false);
+ pTriangLayerTableRecord->setIsFrozen(false);
+ pTriangLayerTableRecord->setIsOff(false);
+ pTriangLayerTableRecord->setIsHidden(false);
+ if ( Acad::eOk != pLayerTable->add(pTriangLayerTableRecord) ) {
+ acutPrintf(_T("\nError adding TRIANG Layer"));
+ acdbTransactionManager->abortTransaction();
+ return 2;
+ }
+ acdbTransactionManager->addNewlyCreatedDBRObject(pTriangLayerTableRecord);
+ } else {
+ acutPrintf(_T("\nTRIANG Layer already exists"));
+ }
+ acdbTransactionManager->endTransaction();
+ return RTNORM;
+ }
+ static bool isEdgeAngleInsidePolygon(Node* node) {
+ bool res = false;
+ return res;
+ }
+ static int Greedy(AcDbPolyline*& pPolyline) {
+ std::vector<Node*> nodes;
+ for(unsigned i=0;i<pPolyline->numVerts();i++) {
+ AcGePoint3d p;
+ pPolyline->getPointAt(i,p);
+ bool contains = false;
+ for(std::vector<Node*>::iterator it = nodes.begin();it!=nodes.end();it++) {
+ if((*it)->v == p.asVector()) {
+ contains = true;
+ break;
+ }
+ }
+ if(!contains) {
+ Node* node = new Node(p,i);
+ nodes.push_back(node);
+ }
+ }
+ unsigned N = nodes.size();
+ // NT: Number of inner edges needed, see lecture pdf 7.1.2, page 126
+ unsigned NT = N - 3;
+
+ acutPrintf(_T("\nNo. Edges: %d, no. triangle edges: %d"),N,NT);
+
+ std::list<Edge*> edgePool;
+ std::list<Edge*> triangEdges;
+ Node* pStartNode;
+ Node* pEndNode;
+ Edge* edge = NULL;
+
+ // generate all edges
+ for (size_t c=0;c<nodes.size()-1;c++) {
+ for(size_t j=c+1;j<nodes.size();j++) {
+ pStartNode=nodes[c];
+ pEndNode=nodes[j];
+ if( c==0 && j==nodes.size()-1) {
+ edge = new Edge(pEndNode,pStartNode,CONTOUR);
+ acutPrintf(_T("\nAdding Contour Edge [%d ; %d]"),edge->startNode->nodeIdx,edge->endNode->nodeIdx);
+ } else if(j-c==1) {
+ edge = new Edge(pStartNode,pEndNode,CONTOUR);
+ acutPrintf(_T("\nAdding Contour Edge [%d ; %d]"),edge->startNode->nodeIdx,edge->endNode->nodeIdx);
+ } else {
+ edge = new Edge(pStartNode,pEndNode,TRIANG);
+ acutPrintf(_T("\nAdding TRIANG Edge [%d ; %d]"),edge->startNode->nodeIdx,edge->endNode->nodeIdx);
+ }
+ if(std::abs(edge->length) > std::numeric_limits<double>::epsilon()) {
+ edgePool.push_back(edge);
+ }
+ }
+ }
+
+ // calc startAngle and endAngle for all Nodes
+ std::vector<Node*>::iterator nodeIter;
+ std::list<Edge*>::iterator edgeIter;
+ /*for(nodeIter = nodes.begin(); nodeIter != nodes.end(); nodeIter++) {
+ Node* node = *nodeIter;
+ for(edgeIter = edgePool.begin(); edgeIter!=edgePool.end(); edgeIter++) {
+ Edge* edge = *edgeIter;
+ if(edge->type == CONTOUR) {
+ if(node == edge->startNode ) {
+ node->leavingAngle = edge->getAngleToXaxisDeg();
+ } else if(node == edge->endNode) {
+ node->arrivingAngle = edge->getAngleToXaxisDeg();
+ }
+ }
+ }
+ }*/
+ AcGeVector3d xAxis(1.0,0.0,0.0);
+ for (size_t c=0;c<nodes.size()-1;c++) {
+ for(size_t j=c+1;j<nodes.size();j++) {
+ bool areNeighboorNodes = false;
+ if( (c==0 && j==nodes.size()-1) ) {
+ pStartNode=nodes[j];
+ pEndNode=nodes[c];
+ areNeighboorNodes = true;
+ } else if(j-c==1) {
+ pStartNode=nodes[c];
+ pEndNode=nodes[j];
+ areNeighboorNodes = true;
+ } else {
+ areNeighboorNodes = false;
+ }
+ if(areNeighboorNodes) {
+ pStartNode->leavingAngle = (std::atan2(pEndNode->v.y - pStartNode->v.y,pEndNode->v.x - pStartNode->v.x)*180.0) / pi;
+ if(pStartNode->leavingAngle < 0.0) {
+ pStartNode->leavingAngle += 360.0;
+ }
+ pEndNode->arrivingAngle = (std::atan2(pStartNode->v.y - pEndNode->v.y,pStartNode->v.x - pEndNode->v.x)*180.0) / pi;
+ if(pEndNode->arrivingAngle < 0.0) {
+ pEndNode->arrivingAngle += 360.0;
+ }
+ }
+ }
+ }
+
+ for(nodeIter = nodes.begin(); nodeIter != nodes.end(); nodeIter++) {
+ Node* node = *nodeIter;
+ if(node->arrivingAngle > node->leavingAngle) {
+ node->leavingAngle += 360.0;
+ }
+ }
+ for(nodeIter = nodes.begin(); nodeIter != nodes.end(); nodeIter++) {
+ Node* node = *nodeIter;
+ acutPrintf(_T("\nNode: %d start: %f, end %f"),node->nodeIdx,node->arrivingAngle,node->leavingAngle);
+ }
+ //unsigned n=0;
+ //for(edgeIter = edgePool.begin(); edgeIter!=edgePool.end(); edgeIter++) {
+ // acutPrintf(_T("\nNo: %d length: %f"),++n,(*edgeIter)->length );
+ //}
+ edgePool.sort(edgeComp);
+ //n=0;
+ //for(edgeIter = edgePool.begin(); edgeIter!=edgePool.end(); edgeIter++) {
+ // acutPrintf(_T("\nNo: %d length: %f"),++n,(*edgeIter)->length );
+ //}
+ acutPrintf(_T("\nEdge pool size: %d"),edgePool.size() );
+
+ // first all all contour edges
+ for (edgeIter = edgePool.begin();edgeIter!=edgePool.end();edgeIter++)
+ {
+ Edge* pEdge = *edgeIter;
+ if( pEdge->type == CONTOUR) {
+ triangEdges.push_back(pEdge);
+ }
+ }
+ unsigned numInnerEdges = 0;
+ for (edgeIter = edgePool.begin();edgeIter!=edgePool.end();edgeIter++)
+ {
+ if(numInnerEdges >= NT) {
+ break;
+ }
+ Edge* pEdge = *edgeIter;
+ if( pEdge->type != CONTOUR) {
+ // check angle
+ if( !pEdge->isEdgeOutsidePolygon() ) {
+ acutPrintf(_T("\n[%d;%d] Edge angle valid: startnode start %f, end %f, endnode start %f, end %f, edge angle %f, inv: %f"),pEdge->startNode->nodeIdx,pEdge->endNode->nodeIdx,pEdge->startNode->arrivingAngle,pEdge->startNode->leavingAngle,pEdge->endNode->arrivingAngle,pEdge->endNode->leavingAngle,(pEdge->getAngleToXaxisDeg()<=360)?pEdge->getAngleToXaxisDeg():pEdge->getAngleToXaxisDeg()+360,pEdge->getInvAngleToXaxisDeg());
+ bool intersectsAnEdge = false;
+ for(std::list<Edge*>::iterator triangIter = triangEdges.begin();triangIter!=triangEdges.end();triangIter++) {
+ Edge triangEdge = **triangIter;
+ if( triangEdge.intersects(*pEdge) ) {
+ acutPrintf(_T("\nFound intersecting edges: [%d,%d] | [%d,%d]"),pEdge->startNode->nodeIdx,pEdge->endNode->nodeIdx,triangEdge.startNode->nodeIdx,triangEdge.endNode->nodeIdx);
+ intersectsAnEdge = true;
+ break;
+ }
+ }
+ if(!intersectsAnEdge) {
+ triangEdges.push_back(pEdge);
+ numInnerEdges++;
+ }
+ } else {
+ acutPrintf(_T("\n[%d;%d] Edge angle invalid: startnode start %f, end %f, endnode start %f, end %f, edge angle %f, inv: %f"),pEdge->startNode->nodeIdx,pEdge->endNode->nodeIdx,pEdge->startNode->arrivingAngle,pEdge->startNode->leavingAngle,pEdge->endNode->arrivingAngle,pEdge->endNode->leavingAngle,(pEdge->getAngleToXaxisDeg()<=360)?pEdge->getAngleToXaxisDeg():pEdge->getAngleToXaxisDeg()+360,pEdge->getInvAngleToXaxisDeg());
+ }
+
+ }
+ }
+ triangEdges.sort(triangEdgeComp);
+ acutPrintf(_T("\nFound %d triangle edges"),triangEdges.size() );
+
+ for(std::list<Edge*>::iterator triangIter = triangEdges.begin();triangIter!=triangEdges.end();triangIter++) {
+ Edge* e1 = *triangIter;
+ Edge* e2;
+ Edge* e3;
+ AcGePoint3d* p1 = NULL;
+ AcGePoint3d* p2 = NULL;
+ AcGePoint3d* p3 = NULL;
+ AcDbFace* pFace = NULL;
+ bool foundAFace = false;
+ for(std::list<Edge*>::iterator e2it = triangIter;e2it!=triangEdges.end();e2it++) {
+ e2=*e2it;
+ //if( ( e1->idx2 == e2->idx1) || (e1->idx1 == e2->idx1) ) {
+ for(std::list<Edge*>::iterator e3it = e2it;e3it!=triangEdges.end();e3it++) {
+ foundAFace = false;
+ e3 = (*e3it);
+ if( (*e1 != *e2) && (*e2 != *e3) && (*e1 != *e3) ) {
+ if( (e1->startNode->nodeIdx == e3->endNode->nodeIdx) && (e2->endNode->nodeIdx == e3->startNode->nodeIdx) && (e1->endNode->nodeIdx == e2->startNode->nodeIdx) ) {
+ p1 = new AcGePoint3d(e1->startNode->v.x,e1->startNode->v.y,0);
+ p2 = new AcGePoint3d(e2->startNode->v.x,e2->startNode->v.y,0);
+ p3 = new AcGePoint3d(e3->startNode->v.x,e3->startNode->v.y,0);
+ foundAFace = true;
+ } else if( (e1->startNode->nodeIdx == e2->startNode->nodeIdx) && (e2->endNode->nodeIdx == e3->endNode->nodeIdx) && (e3->startNode->nodeIdx == e1->endNode->nodeIdx) ) {
+ p1 = new AcGePoint3d(e1->startNode->v.x,e1->startNode->v.y,0);
+ p2 = new AcGePoint3d(e3->startNode->v.x,e3->startNode->v.y,0);
+ p3 = new AcGePoint3d(e3->endNode->v.x,e3->endNode->v.y,0);
+ foundAFace = true;
+ }
+ if(foundAFace) {
+ pFace = new AcDbFace(*p1,*p2,*p3,*p1,Adesk::kFalse,Adesk::kFalse,Adesk::kFalse,Adesk::kFalse);
+ pFace->setLayer(TRIANG_LAYER);
+ addObject((AcDbEntity*&) pFace);
+ acutPrintf(_T("\nPainting a face %d;%d %d;%d %d;%d"),e1->startNode->nodeIdx,e1->endNode->nodeIdx,e2->startNode->nodeIdx,e2->endNode->nodeIdx,e3->startNode->nodeIdx,e3->endNode->nodeIdx);
+ foundAFace = false;
+ }
+ }
+ } // e3it
+ //} //if
+ } // e2it
+ } // triangIter
+
+ return RTNORM;
+ }
+} ;
+
+//-----------------------------------------------------------------------------
+IMPLEMENT_ARX_ENTRYPOINT(CPrakt5GreedyApp)
+
+ACED_ARXCOMMAND_ENTRY_AUTO(CPrakt5GreedyApp, CGCAD_seiPrakt5Greedy, _Greedy, Greedy, ACRX_CMD_MODAL, NULL)
|
