Exemplo n.º 1
0
vector<ofVec3f> ofApp::offsetCell(list<int> & crv, float amt) {
	float scaling = 10;
	ClipperOffset co;
	Path P;
	Paths offsetP;
	float offset = amt;

	for (auto index : crv) {
		ofVec3f v = linesMesh.getVertex(index);
		P.push_back(IntPoint(v.x*scaling, v.y*scaling));
	}
	co.AddPath(P, jtRound, etClosedPolygon);
	co.Execute(offsetP, -offset*scaling);

	vector<ofVec3f> offsetPts;
	if (offsetP.size() > 0) {
		//visual offset for etching
		CleanPolygons(offsetP);

		if (doEtchOffset) {
			co.Clear();
			co.AddPaths(offsetP, jtRound, etClosedPolygon);
			co.Execute(offsetP, -etchOffset*scaling);
		}

		Path & oP = offsetP[0];
		for (int i = 0; i < oP.size(); i++) {
			ofVec3f pt3D(oP[i].X / scaling, oP[i].Y / scaling);
			offsetPts.push_back(pt3D);
		}
	}
	return offsetPts;
}
Exemplo n.º 2
0
vector<ofVec3f> ofApp::offsetCell(list<int> & crv, AnisoPoint2f & pt) {
	float scaling = 1000;
	ClipperOffset co;
	co.ArcTolerance = 1;
	Path P;
	Paths offsetP;
	float offset = ofClamp(offsetPercent / sqrt(pt.jacobian->determinant()), minThick*0.5, maxThick*0.5);

	if (doSmooth) {
		
		for (auto index : crv) {
			ofVec3f v = linesMesh.getVertex(index);
			IntPoint iPt(v.x * scaling, v.y * scaling);
			P.push_back(iPt);
		}
		co.AddPath(P, jtRound, etClosedPolygon);
		co.Execute(offsetP, -offset*scaling);
		if(offsetP.size() == 0) return vector<ofVec3f>();
		P.clear();
		ofVec2f center;
		for (auto & v : offsetP[0]) {
			//ofVec3f v = linesMesh.getVertex(index);
			Vector2f p(v.X, v.Y);
			p = (*pt.jacobian)*p;
			IntPoint iPt(p.coeff(0), p.coeff(1));
			P.push_back(iPt);
			center += ofVec2f(iPt.X, iPt.Y);
		}
		center /= crv.size();
		CleanPolygon(P);
		
		co.Clear();
		co.AddPath(P, jtRound, etClosedPolygon);
		float radius = 9e20;

		//get exact radius from straight skeleton
		Polygon_2 poly;
		for (auto & pt : P) {
			poly.push_back(Point_2(pt.X, pt.Y));
		}
		boost::shared_ptr<Ss> iss = CGAL::create_interior_straight_skeleton_2(poly.vertices_begin(), poly.vertices_end());
		radius = 0;
		for (Ss::Vertex_handle vh = iss->vertices_begin(); vh != iss->vertices_end(); vh++) {
			if (!vh->has_infinite_time()) {
				radius = max(radius, (float)vh->time());
			}
		}

		//estimate radius
		//for (auto & iPt : P) {
		//	radius = min(radius, (iPt.X - center.x)*(iPt.X - center.x) + (iPt.Y - center.y)*(iPt.Y - center.y));
		//}
		//radius = sqrt(radius);
		//co.Execute(offsetP, -radius);
		//int tries = 0;
		//while (offsetP.size() == 0 && tries < 50) {
		//	radius *= .95;
		//	co.Execute(offsetP, -radius);
		//	tries++;
		//}
		//cout << tries << endl;
		radius *= filletPercent;
		co.Execute(offsetP, -radius);
		//radius = min(radius,(radius - offset*scaling)*filletPercent + offset*scaling);
		
		//co.Execute(offsetP, -offset*scaling);
		vector<ofVec3f> offsetPts;
		if (offsetP.size() > 0) {
			//visual offset for etching
			co.Clear();
			CleanPolygons(offsetP);
			co.AddPaths(offsetP, jtRound, etClosedPolygon);
			co.Execute(offsetP, radius);
			CleanPolygons(offsetP);
			Path longestP;
			int pLen = 0;
			for (auto & oP : offsetP) {
				if (oP.size() > pLen) {
					pLen = oP.size();
					longestP = oP;
				}
			}
			Matrix2f inverse = pt.jacobian->inverse();
			if (doEtchOffset) {
				co.Clear();
				for (auto & lPt : longestP) {
					Vector2f anisoPt(lPt.X, lPt.Y);
					anisoPt = inverse*anisoPt;
					lPt.X = anisoPt[0];
					lPt.Y = anisoPt[1];
				}
				co.AddPath(longestP, jtRound, etClosedPolygon);
				co.Execute(offsetP, etchOffset*scaling);
				longestP = offsetP[0];
			}
			for (int i = 0; i < longestP.size(); i++) {
				//ofVec3f pt3D(oP[i].X / scaling, oP[i].Y/ scaling);
				Vector2f anisoPt(longestP[i].X / scaling, longestP[i].Y / scaling);
				if(!doEtchOffset)anisoPt = inverse*anisoPt;
				offsetPts.push_back(ofVec3f(anisoPt.coeff(0), anisoPt.coeff(1)));
			}
		}
		return offsetPts;
	}
	else {
		for (auto index : crv) {
			ofVec3f v = linesMesh.getVertex(index);
			IntPoint iPt(v.x * scaling, v.y * scaling);
			P.push_back(iPt);
		}
		CleanPolygon(P);
		//Paths simplerP;
		//SimplifyPolygon(P, simplerP);
		//CleanPolygons(simplerP);
		//P = simplerP[0];
		//CleanPolygon(P);
		//Polygon_2 poly;
		//for (auto & pt : P) {
		//	poly.push_back(Point_2(pt.X, pt.Y));
		//}
		//boost::shared_ptr<Ss> iss = CGAL::create_interior_straight_skeleton_2(poly.vertices_begin(), poly.vertices_end());
		//float radius = 0;
		//for (Ss::Vertex_handle vh = iss->vertices_begin(); vh != iss->vertices_end(); vh++) {
		//	if (!vh->has_infinite_time()) {
		//		radius = max(radius, (float)vh->time());
		//	}
		//}
		
		//Paths simplerP;
		//SimplifyPolygon(P, simplerP);
		//co.AddPaths(simplerP, jtRound, etClosedPolygon);
		//radius = ofClamp(radius*offsetPercent, minThick*0.5*scaling, maxThick*0.5*scaling);
		co.AddPath(P, jtRound, etClosedPolygon);
		co.Execute(offsetP, -offset*scaling);
		vector<ofVec3f> offsetPts;
		if (offsetP.size() > 0) {
			CleanPolygons(offsetP);
			if (doEtchOffset) {
				co.Clear();
				co.AddPaths(offsetP, jtRound, etClosedPolygon);
				co.Execute(offsetP, etchOffset*scaling);
			}
			else {
				co.Clear();
				co.AddPaths(offsetP, jtRound, etClosedPolygon);
				co.Execute(offsetP, 1);
			}
			Path longestP;
			int pLen = 0;
			for (auto & oP : offsetP) {
				if (oP.size() > pLen) {
					pLen = oP.size();
					longestP = oP;
				}
			}
			Path & oP = longestP;
			for (int i = 0; i < oP.size(); i++) {
				ofVec3f pt3D(oP[i].X / scaling, oP[i].Y/ scaling);
				offsetPts.push_back(pt3D);
			}
		}
		return offsetPts;
	}

}
Exemplo n.º 3
0
void Boundary::Draw( ODDC& dc, PlugIn_ViewPort &piVP )
{
    //ODPath::Draw( dc, piVP );
    if ( m_bVisible && m_pODPointList->GetCount() > 2) {
        int l_iBoundaryPointCount = 0;
        m_bpts = new wxPoint[ m_pODPointList->GetCount() ];
        wxPoint r;
        for(wxODPointListNode *node = m_pODPointList->GetFirst(); node; node = node->GetNext()) {
            ODPoint *pOp = node->GetData();
            GetCanvasPixLL( &piVP, &r, pOp->m_lat, pOp->m_lon );
            m_bpts[ l_iBoundaryPointCount++ ] = r;
        }
        
        if( m_bExclusionBoundary && !m_bInclusionBoundary ) {
            // fill boundary with hatching
            wxGraphicsContext *wxGC = NULL;
            wxMemoryDC *pmdc = wxDynamicCast(dc.GetDC(), wxMemoryDC);
            if( pmdc ) wxGC = wxGraphicsContext::Create( *pmdc );
            else {
                wxClientDC *pcdc = wxDynamicCast(dc.GetDC(), wxClientDC);
                if( pcdc ) wxGC = wxGraphicsContext::Create( *pcdc );
            }
            
            wxGC->SetPen(*wxTRANSPARENT_PEN);
            wxColour tCol;
            tCol.Set(m_fillcol.Red(), m_fillcol.Green(), m_fillcol.Blue(), m_uiFillTransparency);
            wxGC->SetBrush( *wxTheBrushList->FindOrCreateBrush( tCol, wxBRUSHSTYLE_CROSSDIAG_HATCH ) );
            wxGraphicsPath path = wxGC->CreatePath();
            path.MoveToPoint(m_bpts[0].x, m_bpts[0].y);
            for( size_t i = 1; i < m_pODPointList->GetCount(); i++ )
            {
                path.AddLineToPoint(m_bpts[i].x, m_bpts[i].y);
            }
            path.CloseSubpath();
            wxGC->StrokePath(path);
            wxGC->FillPath( path );
            delete wxGC;
        } else if( !m_bExclusionBoundary && m_bInclusionBoundary && m_pODPointList->GetCount() > 3 ) {
            // surround boundary with hatching if there is more than 10 pixels different between points
            int l_imaxpointdiffX = 0;
            int l_imaxpointdiffY = 0;
            for( size_t i = 1; i < m_pODPointList->GetCount(); i++ ) {
                int l_ipointdiffX = abs(m_bpts[0].x - m_bpts[i].x);
                int l_ipointdiffY = abs(m_bpts[0].y - m_bpts[i].y);
                if(l_ipointdiffX > l_imaxpointdiffX) l_imaxpointdiffX = l_ipointdiffX;
                if(l_ipointdiffY > l_imaxpointdiffY) l_imaxpointdiffY = l_ipointdiffY;
            }
            if(l_imaxpointdiffX < 10 && l_imaxpointdiffY < 10 ) return;

            // Use ClipperLib to manage Polygon 
            // If needed simplify polygons to make shading stay outside
            Paths poly(1);
            for( size_t i = 0; i < m_pODPointList->GetCount(); i++ ) {
                poly[0] << IntPoint( m_bpts[i].x, m_bpts[i].y );
            }
            Paths polys;
            SimplifyPolygons( poly, polys );
            ClipperOffset co;
            Paths ExpandedBoundaries;
            co.AddPaths( polys, jtSquare, etClosedPolygon );
            co.Execute( ExpandedBoundaries, m_iInclusionBoundarySize );
            
            wxPoint *l_InclusionBoundary = new wxPoint[ ExpandedBoundaries[0].size() + 1 ];
            for( size_t i = 0; i < ExpandedBoundaries[0].size(); i++ )
            {
                l_InclusionBoundary[i].x = ExpandedBoundaries[0][i].X;
                l_InclusionBoundary[i].y = ExpandedBoundaries[0][i].Y;
            }
            // need to add first point to end to ensure the polygon is closed
            l_InclusionBoundary[ ExpandedBoundaries[0].size()].x = ExpandedBoundaries[0][0].X;
            l_InclusionBoundary[ ExpandedBoundaries[0].size()].y = ExpandedBoundaries[0][0].Y;

            int *l_iPolygonPointCount = new int[2];
            l_iPolygonPointCount[0] = m_pODPointList->GetCount();
            l_iPolygonPointCount[1] = ExpandedBoundaries[0].size() + 1;
            
            wxGraphicsContext *wxGC = NULL;
            wxMemoryDC *pmdc = wxDynamicCast(dc.GetDC(), wxMemoryDC);
            if( pmdc ) wxGC = wxGraphicsContext::Create( *pmdc );
            else {
                wxClientDC *pcdc = wxDynamicCast(dc.GetDC(), wxClientDC);
                if( pcdc ) wxGC = wxGraphicsContext::Create( *pcdc );
            }
            
            wxGC->SetPen(*wxTRANSPARENT_PEN);
            wxColour tCol;
            tCol.Set(m_fillcol.Red(), m_fillcol.Green(), m_fillcol.Blue(), m_uiFillTransparency);
            wxGC->SetBrush( *wxTheBrushList->FindOrCreateBrush( tCol, wxBRUSHSTYLE_CROSSDIAG_HATCH ) );
            wxGraphicsPath path = wxGC->CreatePath();
            path.MoveToPoint(m_bpts[0].x, m_bpts[0].y);
            for( int i = 0; i < l_iPolygonPointCount[0]; i++ ) {
                path.AddLineToPoint(m_bpts[i].x, m_bpts[i].y);
            }
            path.MoveToPoint(l_InclusionBoundary[0].x, l_InclusionBoundary[0].y);
            for( int i = 1; i < l_iPolygonPointCount[1]; i++ ) {
                path.AddLineToPoint(l_InclusionBoundary[i].x, l_InclusionBoundary[i].y);
            }
            path.CloseSubpath();
            wxGC->StrokePath(path);
            wxGC->FillPath( path );
            delete wxGC;
            ExpandedBoundaries.clear();
            polys.clear();
            poly.clear();
            co.Clear();
        }
        wxDELETEA( m_bpts );
    }

    
    ODPath::Draw( dc, piVP );
}