⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs_hatch.cpp

📁 qcad2.05可用于windows和linux的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** $Id: rs_hatch.cpp 2367 2005-04-04 16:57:36Z andrew $**** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.**** This file is part of the qcadlib Library project.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid qcadlib Professional Edition licenses may use ** this file in accordance with the qcadlib Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.ribbonsoft.com for further details.**** Contact info@ribbonsoft.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "rs_hatch.h"#include "rs_graphicview.h"#include "rs_graphic.h"#include "rs_information.h"#include "rs_painter.h"#include "rs_painterqt.h"#include "rs_pointarray.h"#include "rs_pattern.h"#include "rs_patternlist.h"#include <qptrvector.h>/** * Constructor. */RS_Hatch::RS_Hatch(RS_EntityContainer* parent,                   const RS_HatchData& d)        : RS_EntityContainer(parent), data(d) {    hatch = NULL;    updateRunning = false;    needOptimization = true;}/** * Validates the hatch. */bool RS_Hatch::validate() {	bool ret = true;	    // loops:    for (RS_Entity* l=firstEntity(RS2::ResolveNone);            l!=NULL;            l=nextEntity(RS2::ResolveNone)) {        if (l->rtti()==RS2::EntityContainer) {            RS_EntityContainer* loop = (RS_EntityContainer*)l;            ret = loop->optimizeContours() && ret;        }    }	return ret;}    RS_Entity* RS_Hatch::clone() {    RS_Hatch* t = new RS_Hatch(*this);	t->entities.setAutoDelete(entities.autoDelete());    t->initId();    t->detach();	t->hatch = NULL;    return t;}/** * @return Number of loops. */int RS_Hatch::countLoops() {    if (data.solid) {        return count();    } else {        return count() - 1;    }}/** * Recalculates the borders of this hatch. */void RS_Hatch::calculateBorders() {    RS_DEBUG->print("RS_Hatch::calculateBorders");    activateContour(true);    RS_EntityContainer::calculateBorders();	RS_DEBUG->print("RS_Hatch::calculateBorders: size: %f,%f", 		getSize().x, getSize().y);    activateContour(false);}/** * Updates the Hatch. Called when the  * hatch or it's data, position, alignment, .. changes. */void RS_Hatch::update() {	RS_DEBUG->print("RS_Hatch::update");	RS_DEBUG->print("RS_Hatch::update: contour has %d loops", count());#if QT_VERSION>=0x030000    if (updateRunning) {        return;    }    if (updateEnabled==false) {        return;    }    if (data.solid==true) {        return;    }    RS_DEBUG->print("RS_Hatch::update");    updateRunning = true;    // delete old hatch:    if (hatch!=NULL) {        removeEntity(hatch);        hatch = NULL;    }    if (isUndone()) {        updateRunning = false;        return;    }	if (!validate()) {		RS_DEBUG->print(RS_Debug::D_WARNING,			"RS_Hatch::update: invalid contour in hatch found");        updateRunning = false;		return;	}    // search pattern:    RS_DEBUG->print("RS_Hatch::update: requesting pattern");    RS_Pattern* pat = RS_PATTERNLIST->requestPattern(data.pattern);    if (pat==NULL) {        updateRunning = false;        RS_DEBUG->print("RS_Hatch::update: requesting pattern: not found");        return;    }    RS_DEBUG->print("RS_Hatch::update: requesting pattern: OK");    RS_DEBUG->print("RS_Hatch::update: cloning pattern");    pat = (RS_Pattern*)pat->clone();    RS_DEBUG->print("RS_Hatch::update: cloning pattern: OK");    // scale pattern    RS_DEBUG->print("RS_Hatch::update: scaling pattern");    pat->scale(RS_Vector(0.0,0.0), RS_Vector(data.scale, data.scale));    pat->calculateBorders();    forcedCalculateBorders();    RS_DEBUG->print("RS_Hatch::update: scaling pattern: OK");    // find out how many pattern-instances we need in x/y:    int px1, py1, px2, py2;    double f;    RS_Hatch* copy = (RS_Hatch*)this->clone();    copy->rotate(RS_Vector(0.0,0.0), -data.angle);    copy->forcedCalculateBorders();    // create a pattern over the whole contour.    RS_Vector pSize = pat->getSize();    RS_Vector cPos = getMin();    RS_Vector cSize = getSize();    RS_DEBUG->print("RS_Hatch::update: pattern size: %f/%f", pSize.x, pSize.y);    RS_DEBUG->print("RS_Hatch::update: contour size: %f/%f", cSize.x, cSize.y);    if (cSize.x<1.0e-6 || cSize.y<1.0e-6 ||            pSize.x<1.0e-6 || pSize.y<1.0e-6 ||            cSize.x>RS_MAXDOUBLE-1 || cSize.y>RS_MAXDOUBLE-1 ||            pSize.x>RS_MAXDOUBLE-1 || pSize.y>RS_MAXDOUBLE-1) {        delete pat;        delete copy;        updateRunning = false;        RS_DEBUG->print("RS_Hatch::update: contour size or pattern size too small");        return;    }    // avoid huge memory consumption:    else if (cSize.x/pSize.x>100 || cSize.y/pSize.y>100) {        RS_DEBUG->print("RS_Hatch::update: contour size too large or pattern size too small");        return;    }    f = copy->getMin().x/pat->getSize().x;    px1 = (int)floor(f);    f = copy->getMin().y/pat->getSize().y;    py1 = (int)floor(f);    f = copy->getMax().x/pat->getSize().x;    px2 = (int)ceil(f) - 1;    f = copy->getMax().y/pat->getSize().y;    py2 = (int)ceil(f) - 1;    RS_EntityContainer tmp;   // container for untrimmed lines    // adding array of patterns to tmp:    RS_DEBUG->print("RS_Hatch::update: creating pattern carpet");    for (int px=px1; px<=px2; px++) {        for (int py=py1; py<=py2; py++) {            for (RS_Entity* e=pat->firstEntity(); e!=NULL;                    e=pat->nextEntity()) {                RS_Entity* te = e->clone();                te->rotate(RS_Vector(0.0,0.0), data.angle);                RS_Vector v1, v2;                v1.setPolar(px*pSize.x, data.angle);                v2.setPolar(py*pSize.y, data.angle+M_PI/2.0);                te->move(v1+v2);                tmp.addEntity(te);            }        }    }    delete pat;    pat = NULL;    RS_DEBUG->print("RS_Hatch::update: creating pattern carpet: OK");    RS_DEBUG->print("RS_Hatch::update: cutting pattern carpet");    // cut pattern to contour shape:    RS_EntityContainer tmp2;   // container for small cut lines    RS_Line* line = NULL;    RS_Arc* arc = NULL;    RS_Circle* circle = NULL;    for (RS_Entity* e=tmp.firstEntity(); e!=NULL;            e=tmp.nextEntity()) {        RS_Vector startPoint;        RS_Vector endPoint;        RS_Vector center = RS_Vector(false);        bool reversed;        if (e->rtti()==RS2::EntityLine) {            line = (RS_Line*)e;            arc = NULL;            circle = NULL;            startPoint = line->getStartpoint();            endPoint = line->getEndpoint();            center = RS_Vector(false);            reversed = false;        } else if (e->rtti()==RS2::EntityArc) {            arc = (RS_Arc*)e;            line = NULL;            circle = NULL;            startPoint = arc->getStartpoint();            endPoint = arc->getEndpoint();            center = arc->getCenter();            reversed = arc->isReversed();        } else if (e->rtti()==RS2::EntityCircle) {            circle = (RS_Circle*)e;            line = NULL;            arc = NULL;            startPoint = circle->getCenter()                         + RS_Vector(circle->getRadius(), 0.0);            endPoint = startPoint;            center = circle->getCenter();            reversed = false;        } else {            continue;        }        // getting all intersections of this pattern line with the contour:        RS_PtrList<RS_Vector> is;        is.setAutoDelete(true);        is.append(new RS_Vector(startPoint));        for (RS_Entity* loop=firstEntity(); loop!=NULL;                loop=nextEntity()) {            if (loop->isContainer()) {                for (RS_Entity* p=((RS_EntityContainer*)loop)->firstEntity();                        p!=NULL;                        p=((RS_EntityContainer*)loop)->nextEntity()) {                    RS_VectorSolutions sol =                        RS_Information::getIntersection(e, p, true);                    for (int i=0; i<=1; ++i) {                        if (sol.get(i).valid) {                            is.append(new RS_Vector(sol.get(i)));                            RS_DEBUG->print("  pattern line intersection: %f/%f",                                            sol.get(i).x, sol.get(i).y);                        }                    }                }            }        }        is.append(new RS_Vector(endPoint));        // sort the intersection points into is2:        RS_Vector sp = startPoint;        double sa = center.angleTo(sp);        RS_PtrList<RS_Vector> is2;        is2.setAutoDelete(true);        bool done;        double minDist;        double dist = 0.0;        RS_Vector* av;        RS_Vector last = RS_Vector(false);        do {            done = true;            minDist = RS_MAXDOUBLE;            av = NULL;            for (RS_Vector* v = is.first(); v!=NULL; v = is.next()) {                if (line!=NULL) {                    dist = sp.distanceTo(*v);                } else if (arc!=NULL || circle!=NULL) {                    double a = center.angleTo(*v);                    if (reversed) {                        if (a>sa) {                            a-=2*M_PI;                        }                        dist = sa-a;                    } else {                        if (a<sa) {                            a+=2*M_PI;                        }                        dist = a-sa;                    }                    if (fabs(dist-2*M_PI)<1.0e-6) {                        dist = 0.0;                    }                }                if (dist<minDist) {                    minDist = dist;                    done = false;                    av = v;                    //idx = is.at();                }            }            // copy to sorted list, removing double points            if (!done && av!=NULL) {                if (last.valid==false || last.distanceTo(*av)>1.0e-10) {                    is2.append(new RS_Vector(*av));                    last = *av;                }                is.remove(av);                av = NULL;            }        } while(!done);        // add small cut lines / arcs to tmp2:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -