/** * \return That one vector from the given vectors with the largest Y coordinate. */ RVector RVector::getMaximumY(const QList<RVector>& vectors) { if (vectors.size() == 0) { return RVector(); } RVector ret = vectors[0]; for (int i=0; i<vectors.size(); i++) { if (vectors[i].y > ret.y) { ret = vectors[i]; } } return ret; }
/** * \return That one vector from the given vectors with the smallest X coordinate. */ RVector RVector::getMinimumX(const QList<RVector>& vectors) { if (vectors.size() == 0) { return RVector(); } RVector ret = vectors[0]; for (int i=0; i<vectors.size(); i++) { if (vectors[i].x < ret.x) { ret = vectors[i]; } } return ret; }
/** * \return A vector with the maximum components from the given vectors. * These might be mixed components from all vectors. */ RVector RVector::getMaximum(const QList<RVector>& vectors) { if (vectors.size() == 0) { return RVector(); } RVector ret = vectors[0]; QList<RVector>::const_iterator it = vectors.begin(); it++; for (; it != vectors.end(); it++) { ret = getMaximum(ret, *it); } return ret; }
/** * \return Control points of internal spline representation (may be closed). */ QList<RVector> RSpline::getControlPointsWrapped() const { QList<RVector> ret; updateInternal(); #ifndef R_NO_OPENNURBS ON_3dPoint onp; for (int i=0; i<curve.CVCount(); ++i) { curve.GetCV(i, onp); ret.append(RVector(onp.x, onp.y)); } #endif return ret; }
void RDimLinearData::updateTextData() const { initTextData(); double dimgap = getDimgap(); if (RMath::isNaN(defaultAngle)) { // updates default angle: getShapes(); } // move text to the side if appropriate: if (!hasCustomTextPosition()) { // RVector newTextPos = dimensionLine.getMiddlePoint(); // RVector distV; // // rotate text so it's readable from the bottom or right (ISO) // // quadrant 1 & 4 // if (corrected) { // distV.setPolar(dimgap + dimtxt/2.0, dimAngle1-M_PI/2.0); // } else { // distV.setPolar(dimgap + dimtxt/2.0, dimAngle1+M_PI/2.0); // } // // move text away from dimension line: // newTextPos+=distV; // // TODO: resets textPosition if text was moved to the side for lack of space: // textPosition = newTextPos; // qDebug() << "RDimensionData::getDimensionLineShapes(): 1: textPosition: " << textPosition; // //updateTextData(); // qDebug() << "RDimensionData::getDimensionLineShapes(): 2: textPosition: " << textPosition; if (!RMath::isNaN(dimLineLength) && textData.getWidth()>dimLineLength) { RVector distH; distH.setPolar(textData.getWidth()/2.0+dimLineLength/2.0+dimgap, defaultAngle); textPositionSide = textPositionCenter; textPositionSide+=distH; //qDebug() << "RDimLinearData::updateTextData(): textPosition (side): " << textPositionCenter; } else { textPositionSide = RVector::invalid; } } textData.rotate(defaultAngle, RVector(0,0)); textData.move(getTextPosition()); }
/** * \return The angle from zero to this vector (in rad). */ double RVector::getAngle() const { double ret = 0.0; double m = getMagnitude2D(); if (m > 1.0e-6) { double dp = getDotProduct(*this, RVector(1.0, 0.0)); if (dp / m >= 1.0) { ret = 0.0; } else if (dp / m < -1.0) { ret = M_PI; } else { ret = acos(dp / m); } if (y < 0.0) { ret = 2*M_PI - ret; } } return ret; }
void OpenSMOKE_PostProcessor_RateOfProductionAnalysis::ReadFromBinaryFile(BzzLoad &fLoad) { char dummy[Constants::NAME_SIZE]; fLoad.fileLoad.read((char*) dummy, sizeof(dummy)); std::string version = dummy; if (version != "V20100417") ErrorMessage("This version post processing file is not supported: " + version); cout << "Version: " << version << endl; // Indices of species CheckInBinaryFile(fLoad, "INDICES"); fLoad >> indices; // Reaction rates CheckInBinaryFile(fLoad, "REACTIONRATES"); fLoad >> reactionRates; // Preparing data ropa = new OpenSMOKE_RateOfProductionAnalysis(); BzzVector aux_x = post_processor->get_x(); ropa->Initialize(post_processor->mix, indices); ropa->SetNumberOfPoints(aux_x.Size()); ropa->Run(reactionRates, aux_x); // Formation rates { ChangeDimensions(post_processor->get_x().Size(), NC, &formationRates); BzzVector RVector(NC); BzzVector C(NC); for(int j=1;j<=post_processor->get_x().Size();j++) { double T = post_processor->get_T(j); double P_Pa = post_processor->get_P_Pa(j); double Ctot = post_processor->get_Ctot(j); C = post_processor->get_C(j); post_processor->mix->ComputeKineticParameters( T, log(T), 1./T, P_Pa); post_processor->mix->ComputeFromConcentrations( T, C, Ctot, &RVector); // [kmol/m3/s] formationRates.SetRow(j, RVector); // [kmol/m3/s] } } Prepare(); }
/** * \return List of bezier spline segments which together represent this curve. */ QList<RSpline> RSpline::getBezierSegments(const RBox& queryBox) const { // spline is a single bezier segment: if (countControlPoints()==getDegree()+1) { return QList<RSpline>() << *this; } updateInternal(); QList<RSpline> ret; #ifndef R_NO_OPENNURBS ON_NurbsCurve* dup = dynamic_cast<ON_NurbsCurve*>(curve.DuplicateCurve()); if (dup==NULL) { return ret; } dup->MakePiecewiseBezier(); for (int i=0; i<=dup->CVCount() - dup->Order(); ++i) { ON_BezierCurve bc; if (!dup->ConvertSpanToBezier(i, bc)) { continue; } QList<RVector> ctrlPts; for (int cpi=0; cpi<bc.CVCount(); cpi++) { ON_3dPoint onp; bc.GetCV(cpi, onp); ctrlPts.append(RVector(onp.x, onp.y, onp.z)); } RSpline bezierSegment(ctrlPts, degree); if (!queryBox.isValid() || queryBox.intersects(bezierSegment.getBoundingBox())) { ret.append(bezierSegment); } } delete dup; #endif return ret; }
QList<QSharedPointer<RShape> > RDimensionData::getArrow( const RVector& position, double direction) const { QList<QSharedPointer<RShape> > ret; double arrowSize = getDimasz(); // architecture tick: if (useArchTick()) { RVector p1(arrowSize/2, arrowSize/2); RLine line(p1, -p1); line.rotate(direction, RVector(0,0)); line.move(position); ret.append(QSharedPointer<RLine>(new RLine(line))); } // standard arrow: else { RTriangle arrow = RTriangle::createArrow(position, direction, arrowSize); ret.append(QSharedPointer<RTriangle>(new RTriangle(arrow))); } return ret; }
void OpenSMOKE_SensitivityAnalysis_Fast_Flame1D::BuildJAlfaMatrix(BzzVector &T, BzzVector &rho, BzzVector &Cp, vector<string> list_of_names, const double P_Pascal, BzzMatrix &X) { int S_NC = list_of_names.size(); int S_NV = NV-NC+S_NC; int S_NE = S_NV*N; ChangeDimensions(S_NE, NP, &S_S); BzzVector xVector(NC); BzzVector cVector(NC); BzzVector RVector(NC); for(int n=1;n<=N_BLOCKS+1;n++) { int iStart; int iEnd; if (n<N_BLOCKS+1) { cout << "Internal block..." << endl; iStart = NP_BLOCK*(n-1)+1; iEnd = NP_BLOCK*n; } else { cout << "Last block..." << endl; iStart = NP_BLOCK*(n-1)+1; iEnd = NP; ChangeDimensions(NE, NP_RESIDUAL, &JAlfa); ChangeDimensions(NE, NP_RESIDUAL, &S); } cout << "Sensitivity Block #" << n << "/" << N_BLOCKS+1 << endl; JAlfa=0; for(int iPoint=1;iPoint<=N;iPoint++) { int index = (iPoint-1)*NV; JAlfaPoint = 0.; if (iPoint == 1 || iPoint == N) { } else { double cTot = P_Pascal / (Constants::R_J_kmol*T[iPoint]); X.GetRow(iPoint,&xVector); cVector = cTot*xVector; mix->ComputeKineticParameters(T[iPoint], log(T[iPoint]), 1./T[iPoint], P_Pascal); mix->ComputeFromConcentrations(T[iPoint], cVector, cTot, &RVector); if (kindOfParameter == FREQUENCY_FACTOR) mix->GiveMe_Jalfa_A(JAlfaPoint, nu, T[iPoint], indexSpecies, indexTemperature, parameters); else if (kindOfParameter == FREQUENCY_FACTOR_AND_TRANSPORT_PROPERTIES) mix->GiveMe_Jalfa_A(JAlfaPoint, nu, T[iPoint], indexSpecies, indexTemperature, parameters); else ErrorMessage("Wrong Sensitivity Parameter"); //if (kindOfParameter == BETA) mix->GiveMe_Jalfa_Beta(JAlfaPoint, nu, T[iPoint], indexSpecies, indexTemperature, parameters); //if (kindOfParameter == ACTIVATION_ENERGY) mix->GiveMe_Jalfa_Eatt(JAlfaPoint, nu, T[iPoint], indexSpecies, indexTemperature, parameters); for(int k=1;k<=NP;k++) if (parameters[k] <= 0.) ErrorMessage("Parameters must be larger than zero!"); } // Temperature equations if (Cp[1]<0) // this means no energy equation { for(int j=iStart;j<=iEnd;j++) JAlfa[index+indexTemperature][j-iStart+1] = 0; } else { for(int j=iStart;j<=iEnd;j++) JAlfa[index+indexTemperature][j-iStart+1] = JAlfaPoint[indexTemperature][j]/(rho[iPoint]*Cp[iPoint]); } // Species equations for(int i=1;i<=NC;i++) for(int j=iStart;j<=iEnd;j++) JAlfa[index+indexSpecies+i-1][j-iStart+1] = JAlfaPoint[indexSpecies+i-1][j]/rho[iPoint]; } JAlfa *= -1.; Solve(AFactorized, JAlfa, &S); for(int k=iStart;k<=iEnd;k++) { int j; // First Rows for(j=1;j<=indexSpecies-1;j++) for(int i=1;i<=N;i++) S_S[(i-1)*S_NV+j][k] = S[(i-1)*NV+j][k-iStart+1]; // Species Rows for(j=1;j<=S_NC;j++) { int index = mix->recognize_species(list_of_names[j-1]); for(int i=1;i<=N;i++) S_S[(i-1)*S_NV+(j+indexSpecies-1)][k] = S[(i-1)*NV+(index+indexSpecies-1)][k-iStart+1]; } } } }
RVector interpolate(const Mesh & mesh, const RVector & data, const RVector & x, bool verbose){ return interpolate(mesh, data, x, RVector(x.size(), 0.0), RVector(x.size(), 0.0)); }
void ROrthoGrid::paintCursor(const RVector& pos) { // crosshair size: double s = 0; if (!RSettings::getShowLargeCrosshair()) { s = view.mapDistanceFromView(25); } RBox b = view.getBox(); if (isometric) { double dxp, dyp, dxn, dyn; if (RSettings::getShowLargeCrosshair()) { dxp = b.c2.x - pos.x; dyp = tan(M_PI/6) * dxp; dxn = pos.x - b.c1.x; dyn = tan(M_PI/6) * dxn; } else { dxp = dxn = cos(M_PI/6) * s; dyp = dyn = sin(M_PI/6) * s; } // .-´ if (projection==RS::IsoTop || projection==RS::IsoRight) { view.paintGridLine(RLine(pos + RVector(dxp,dyp), pos - RVector(dxn,dyn))); } // `-. if (projection==RS::IsoTop || projection==RS::IsoLeft) { view.paintGridLine(RLine(pos + RVector(dxp,-dyp), pos - RVector(dxn,-dyn))); } // | if (projection==RS::IsoRight || projection==RS::IsoLeft) { if (RSettings::getShowLargeCrosshair()) { view.paintGridLine(RLine(RVector(pos.x, b.c1.y), RVector(pos.x, b.c2.y))); } else { view.paintGridLine(RLine(RVector(pos.x, pos.y - s), RVector(pos.x, pos.y + s))); } } } else { if (RSettings::getShowLargeCrosshair()) { view.paintGridLine(RLine(RVector(b.c1.x, pos.y), RVector(b.c2.x, pos.y))); view.paintGridLine(RLine(RVector(pos.x, b.c1.y), RVector(pos.x, b.c2.y))); } else { double s = view.mapDistanceFromView(25); RVector sx(s, 0); RVector sy(0, s); view.paintGridLine(RLine(pos-sx, pos+sx)); view.paintGridLine(RLine(pos-sy, pos+sy)); } } }
void ROrthoGrid::paintRuler(RRuler& ruler, qreal devicePixelRatio) { RDocument* doc = view.getDocument(); if (doc == NULL) { return; } RS::Unit unit = doc->getUnit(); RS::LinearFormat linearFormat = doc->getLinearFormat(); // use grid spacing if available or auto grid spacing: RVector localSpacing = spacing; if (!localSpacing.isValid() || (autoSpacing.isValid() && autoSpacing.getMagnitude2d() < localSpacing.getMagnitude2d())) { localSpacing = autoSpacing; } // use meta grid spacing if available or auto meta grid spacing: RVector localMetaSpacing = metaSpacing; if (!localMetaSpacing.isValid() || (autoMetaSpacing.isValid() && autoMetaSpacing.getMagnitude2d() < localMetaSpacing.getMagnitude2d())) { //localMetaSpacing = autoMetaSpacing; } //if (!localMetaSpacing.isValid()) { // qDebug() << "no local meta spacing"; // return; //} if (localSpacing.getMagnitude()<1.0e-6 || localMetaSpacing.getMagnitude()<1.0e-6) { //qDebug() << "local (meta) spacing too small"; return; } RVector min = gridBox.getCorner1(); RVector max = gridBox.getCorner2(); bool isHorizontal = ruler.getOrientation() == Qt::Horizontal; double tickSpacing; //if (!RUnit::isMetric(doc->getUnit())) { if (isFractionalFormat(linearFormat) && !RUnit::isMetric(unit)) { if (isHorizontal) { tickSpacing = localSpacing.x; } else { tickSpacing = localSpacing.y; } } else { if (isHorizontal) { tickSpacing = localMetaSpacing.x; } else { tickSpacing = localMetaSpacing.y; } if (view.mapDistanceToView(tickSpacing) >= 80) { tickSpacing /= 10; } else if (view.mapDistanceToView(tickSpacing) >= 30) { tickSpacing /= 5; } else if (view.mapDistanceToView(tickSpacing) >= 20) { tickSpacing /= 2; } } // ideal tick spacing in pixels: int pSpacing = (int) ceil(view.mapDistanceToView(tickSpacing)); QString l1 = RUnit::getLabel(isHorizontal ? min.x : min.y, *doc, false, true); QString l2 = RUnit::getLabel(isHorizontal ? max.x : max.y, *doc, false, true); int labelWidth = std::max( QFontMetrics(ruler.getFont()).boundingRect(l1).width(), QFontMetrics(ruler.getFont()).boundingRect(l2).width()) + 15; // smallest displayable distance between labels in steps (ticks): int minLabelStep = 1; if (pSpacing>0) { minLabelStep = labelWidth / pSpacing + 1; } int labelStep = minLabelStep; //if (!RUnit::isMetric(doc->getUnit())) { if (isFractionalFormat(linearFormat) && !RUnit::isMetric(unit)) { // non metric double f = 1.0/128; do { if (localMetaSpacing.isValid()) { if (isHorizontal) { labelStep = RMath::mround(localMetaSpacing.x / localSpacing.x) * f; } else { labelStep = RMath::mround(localMetaSpacing.y / localSpacing.y) * f; } } else { labelStep = (int)f; } f = f * 2; if (f>65536) { labelStep = -1; } } while (labelStep < minLabelStep && labelStep>=0); } else { // metric if (labelStep >= 3 && labelStep <= 4) { labelStep = 5; } else if (labelStep >= 6 && labelStep <= 9) { labelStep = 10; } else if (labelStep >= 11 && labelStep <= 19) { labelStep = 20; } else if (labelStep >= 21 && labelStep <= 99) { labelStep = 100; } } if (labelStep<0) { return; } if (labelStep<1) { labelStep = 1; } double minPos; double maxPos; if (isHorizontal) { minPos = (floor(view.mapFromView(RVector(0, 0)).x / (labelStep * tickSpacing))-1) * (labelStep * tickSpacing); maxPos = (ceil(view.mapFromView(RVector(view.getWidth(), 0)).x / (labelStep * tickSpacing))+1) * (labelStep * tickSpacing); } else { minPos = (floor(view.mapFromView(RVector(0, view.getHeight())).y / (labelStep * tickSpacing))-1) * (labelStep * tickSpacing); maxPos = (ceil(view.mapFromView(RVector(0, 0)).y / (labelStep * tickSpacing))+1) * (labelStep * tickSpacing); } if ((maxPos - minPos) / tickSpacing > 1e3) { return; } int c; double p; for (c = 0, p = minPos; p < maxPos; p += tickSpacing, ++c) { bool hasLabel = c % labelStep == 0; double v; if (isHorizontal) { v = view.mapToView(RVector(p, 0)).x; } else { v = view.mapToView(RVector(0, p)).y; } ruler.paintTick(v*devicePixelRatio, hasLabel, hasLabel ? RUnit::getLabel(p, *doc, false, true, true) : QString()); } }
QList<RVector> ROrthoGrid::getIdealGridSpacing(RGraphicsView& view, int minPixelSpacing, const RVector& minSpacing, const RVector& minMetaSpacing) { RS::Unit unit = view.getDocument()->getUnit(); RS::LinearFormat linearFormat = view.getDocument()->getLinearFormat(); QList<RVector> ret; if (isFractionalFormat(linearFormat) && !RUnit::isMetric(unit)) { double idealInchSpacing = RUnit::convert(view.mapDistanceFromView(qMax(minPixelSpacing, 1)), unit, RS::Inch); RVector spacing = RUnit::convert(minSpacing, unit, RS::Inch); spacing.x = inchAutoscale(spacing.x, idealInchSpacing, unit); spacing.y = inchAutoscale(spacing.y, idealInchSpacing, unit); spacing = RUnit::convert(spacing, RS::Inch, unit); // never drop below min spacing: if (spacing.x<minSpacing.x) { spacing.x = minSpacing.x; } if (spacing.y<minSpacing.y) { spacing.y = minSpacing.y; } RVector metaSpacing = spacing; // RVector(1.0 / 64, 1.0 / 64, 1.0 / 64); metaSpacing.x = inchAutoscale(metaSpacing.x, idealInchSpacing * 4, unit); metaSpacing.y = inchAutoscale(metaSpacing.y, idealInchSpacing * 4, unit); metaSpacing = RUnit::convert(metaSpacing, RS::Inch, unit); // never drop below min spacing: if (metaSpacing.x<minMetaSpacing.x) { metaSpacing.x = minMetaSpacing.x; } if (metaSpacing.y<minMetaSpacing.y) { metaSpacing.y = minMetaSpacing.y; } // foot: never show meta grid of < 1 foot: if (unit==RS::Foot) { if (metaSpacing.x<1.0) { metaSpacing.x = 1.0; } if (metaSpacing.y<1.0) { metaSpacing.y = 1.0; } } // if (metaSpacing.x < this->metaSpacing.x) { // metaSpacing.x = this->metaSpacing.x; // } ret.append(spacing); ret.append(metaSpacing); return ret; } else { // ideal (minimum) grid spacing for the given view (some odd number): double idealSpacing = view.mapDistanceFromView(qMax(minPixelSpacing, 1)); // idealSpacing = minSpacing * idealFactor RVector idealFactor(idealSpacing / minSpacing.x, idealSpacing / minSpacing.y); // idealFactor = minSpacing * 10^n RVector n(log(idealFactor.x / minSpacing.x) / log(10.0), log(idealFactor.y / minSpacing.y) / log(10.0)); // factor = minSpacing * 10^ceil(n) RVector factor(minSpacing.x * pow(10.0, ceil(n.x - 1.0e-6)), minSpacing.y * pow(10.0, ceil(n.y - 1.0e-6))); // never drop below min spacing: if (factor.x<1.0) { factor.x = 1.0; } if (factor.y<1.0) { factor.y = 1.0; } // grid spacing: double x, y; x = minSpacing.x * factor.x; y = minSpacing.y * factor.y; ret.append(RVector(x,y)); // meta grid spacing: double mx, my; if (RMath::isNaN(minMetaSpacing.x)) { mx = x * 10; } else { //mx = minMetaSpacing.x * factor.x; mx = minMetaSpacing.x; } if (RMath::isNaN(minMetaSpacing.y)) { my = y * 10; } else { //my = minMetaSpacing.y * factor.y; my = minMetaSpacing.y; } ret.append(RVector(mx, my)); //ret.append(RVector(minSpacing.x * factor.x, minSpacing.y * factor.y)); //ret.append(RVector(minMetaSpacing.x * factor.x, minMetaSpacing.y * factor.y)); //ret.append(ret.at(0) * 10); return ret; } }
void ROrthoGrid::paintGridLines(const RVector& space, const RBox& box, bool meta) { if (!space.isValid()) { return; } // updates cache if necessary: getProjection(); isIsometric(); RVector min = box.getCorner1(); RVector max = box.getCorner2(); double deltaX = max.x - min.x; double deltaY = max.y - min.y; if (deltaX / space.x > 1e3 || deltaY / space.y > 1e3) { return; } double dx = deltaY / tan(M_PI/6); if (isometric) { min.x -= dx; max.x += dx; } int c; double x; for (x=min.x, c=0; x<max.x; x+=space.x, c++) { //int x2 = RMath::mround(x/space.x); //if (!isometric || c%2==0) { if (isometric) { if (projection==RS::IsoTop || projection==RS::IsoRight) { view.paintGridLine(RLine(RVector(x, min.y), RVector(x+dx, max.y))); } if (projection==RS::IsoTop || projection==RS::IsoLeft) { view.paintGridLine(RLine(RVector(x, min.y), RVector(x-dx, max.y))); } // vertical grid lines: if (projection==RS::IsoRight || projection==RS::IsoLeft) { view.paintGridLine(RLine(RVector(x, min.y), RVector(x, max.y))); view.paintGridLine(RLine(RVector(x-space.x/2, min.y), RVector(x-space.x/2, max.y))); } } else { view.paintGridLine(RLine(RVector(x, min.y), RVector(x, max.y))); } //} } // horizontal lines: if (!isometric) { for (double y=min.y; y<max.y; y+=space.y) { view.paintGridLine(RLine(RVector(min.x, y), RVector(max.x, y))); } } }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { resize(800, 600); // init script handler for ECMAScript: RScriptHandlerRegistry::registerScriptHandler( RScriptHandlerEcma::factory, RScriptHandlerEcma::getSupportedFileExtensionsStatic() ); RScriptHandlerEcma* handler = dynamic_cast<RScriptHandlerEcma*>(RScriptHandlerRegistry::getGlobalScriptHandler("js")); // create central widget from UI file: // this widget contains a child called 'Viewport00'. This child // widget will be filled with our graphics display with scroll // bars, etc. QFile file("support/examples/mainwindow/MyDisplay.ui"); file.open(QIODevice::ReadOnly); QUiLoader loader; QWidget* widget = loader.load(&file, this); file.close(); setCentralWidget(widget); // create drawing document with document interface: RMemoryStorage* storage = new RMemoryStorage(); RSpatialIndexNavel* spatialIndex = new RSpatialIndexNavel(); RDocument* document = new RDocument(*storage, *spatialIndex); documentInterface = new RDocumentInterface(*document); // import a DXF file into the drawing: documentInterface->importFile("support/examples/mainwindow/drawing_file_to_display.dxf"); // operation used to add various objects: RAddObjectOperation* op; // add a layer 'MyLayer': QSharedPointer<RLayer> layer = QSharedPointer<RLayer>( new RLayer(document, "MyLayer") ); layer->setLinetypeId(document->getLinetypeId("continuous")); op = new RAddObjectOperation(layer); documentInterface->applyOperation(op); RLayer::Id layerId = layer->getId(); // create and add a line entity: QSharedPointer<RLineEntity> lineEntity = QSharedPointer<RLineEntity>( new RLineEntity(document, RLineData(RVector(0,0), RVector(100,0))) ); // set attributes: lineEntity->setLayerId(layerId); lineEntity->setColor(RColor(0,128,255)); lineEntity->setLinetypeId(document->getLinetypeId("dashed")); lineEntity->setLineweight(RLineweight::Weight100); // set a custom property: lineEntity->setCustomProperty("MyIntProperty", 77); lineEntity->setCustomProperty("MyStringProperty", "Some text"); op = new RAddObjectOperation( lineEntity, false // false: don't use current attributes but // custom attributes set above ); // add the line entity to the drawing: documentInterface->applyOperation(op); // make 'widget' and 'documentInterface' available for the script engine: QScriptEngine& engine = handler->getScriptEngine(); QScriptValue globalObject = engine.globalObject(); globalObject.setProperty("widget", engine.newQObject(widget)); globalObject.setProperty("documentInterface", qScriptValueFromValue(&engine, documentInterface)); // call script to initialize viewport (add scroll bars, rulers, etc.): handler->doScript("support/examples/mainwindow/init_viewport.js"); }
/** * Updates the grid information, in particular the grid spacing and * grid region to the current view port. */ void ROrthoGrid::update(bool force) { if (!force && viewBox==view.getBox()) { return; } viewBox = view.getBox(); int viewportNumber = view.getViewportNumber(); RDocument* doc = view.getDocument(); if (doc == NULL) { qWarning() << "ROrthoGrid::update: document is NULL"; return; } RGraphicsScene* scene = view.getScene(); if (scene==NULL) { qWarning() << "ROrthoGrid::update: scene is NULL"; return; } RS::ProjectionRenderingHint hint = scene->getProjectionRenderingHint(); // for 3d views, we have no convenient way to calculate the grid dimensions: if (hint == RS::RenderThreeD) { gridBox = RBox(RVector(-1000, -1000), RVector(1000, 1000)); spacing = RVector(10.0, 10.0); return; } QString key; key = QString("Grid/IsometricGrid0%1").arg(viewportNumber); isometric = doc->getVariable(key, false, true).toBool(); RS::Unit unit = doc->getUnit(); RS::LinearFormat linearFormat = doc->getLinearFormat(); // default values for missing configurations and 'auto' settings: minSpacing.valid = true; minMetaSpacing.valid = true; if (isFractionalFormat(linearFormat) && !RUnit::isMetric(unit)) { //minSpacing.x = minSpacing.y = RNANDOUBLE; //minMetaSpacing.x = minMetaSpacing.y = RNANDOUBLE; minSpacing.x = minSpacing.y = RUnit::convert(1.0, RS::Inch, unit) / 1024; minMetaSpacing.x = minMetaSpacing.y = RUnit::convert(1.0, RS::Inch, unit) / 1024; } else { minSpacing.x = minSpacing.y = 1.0e-6; minMetaSpacing.x = minMetaSpacing.y = RNANDOUBLE; //minSpacing.x = minSpacing.y = RNANDOUBLE; //minMetaSpacing.x = minMetaSpacing.y = 1.0e-6; } key = QString("Grid/GridSpacingX0%1").arg(viewportNumber); QVariant strSx = doc->getVariable(key, QVariant(), true); key = QString("Grid/GridSpacingY0%1").arg(viewportNumber); QVariant strSy = doc->getVariable(key, QVariant(), true); spacing.valid = true; bool autoX = !strSx.isValid() || strSx.toString()=="auto"; bool autoY = !strSy.isValid() || strSy.toString()=="auto"; // grid spacing x: if (!autoX) { // fixed: double d = RMath::eval(strSx.toString()); if (!RMath::hasError() && d>RS::PointTolerance) { minSpacing.x = spacing.x = d; } } // grid spacing y: if (!autoY) { double d = RMath::eval(strSy.toString()); if (!RMath::hasError() && d>RS::PointTolerance) { minSpacing.y = spacing.y = d; } } // meta grid: key = QString("Grid/MetaGridSpacingX0%1").arg(viewportNumber); QVariant strMsx = doc->getVariable(key, QVariant(), true); key = QString("Grid/MetaGridSpacingY0%1").arg(viewportNumber); QVariant strMsy = doc->getVariable(key, QVariant(), true); metaSpacing.valid = true; bool metaAutoX = !strMsx.isValid() || strMsx.toString()=="auto"; bool metaAutoY = !strMsy.isValid() || strMsy.toString()=="auto"; // meta grid spacing x: if (!metaAutoX) { // fixed: double d = RMath::eval(strMsx.toString()); if (d>RS::PointTolerance) { minMetaSpacing.x = metaSpacing.x = d; } } // meta grid spacing y: if (!metaAutoY) { // fixed: double d = RMath::eval(strMsy.toString()); if (d>RS::PointTolerance) { minMetaSpacing.y = metaSpacing.y = d; } } // auto scale grid: QList<RVector> s = getIdealSpacing(minPixelSpacing, minSpacing, minMetaSpacing); if (RSettings::getAutoScaleGrid()) { autoSpacing = spacing = s.at(0); } if (RSettings::getAutoScaleMetaGrid()) { autoMetaSpacing = metaSpacing = s.at(1); } // switch grid off below given pixel limit: if (view.mapDistanceToView(spacing.x) < minPixelSpacing) { spacing = RVector::invalid; } if (view.mapDistanceToView(metaSpacing.x) < minPixelSpacing) { metaSpacing = RVector::invalid; } if (view.mapDistanceToView(spacing.y) < minPixelSpacing) { spacing = RVector::invalid; } if (view.mapDistanceToView(metaSpacing.y) < minPixelSpacing) { metaSpacing = RVector::invalid; } // qDebug() << "spacing: " << spacing; // qDebug() << "minSpacing: " << minSpacing; // qDebug() << "metaSpacing: " << metaSpacing; // if (scaleGrid) { // QList<RVector> s = ROrthoGrid::getIdealSpacing(view, minPixelSpacing, minSpacing); // spacing = s.at(0); // metaSpacing = s.at(1); // } else { // spacing = minSpacing; // } RVector minGridPoint; RVector maxGridPoint; spacing.z = 1; if (isometric) { spacing.x = spacing.y * 2.0 * sin(M_PI/3.0); metaSpacing.x = metaSpacing.y * 2.0 * sin(M_PI/3.0); spacing = spacing / 2; //metaSpacing = metaSpacing / 2; } minGridPoint = viewBox.getCorner1(); minGridPoint = minGridPoint.getDividedComponents(spacing).getFloor(); minGridPoint = minGridPoint.getMultipliedComponents(spacing); maxGridPoint = viewBox.getCorner2(); maxGridPoint = maxGridPoint.getDividedComponents(spacing).getCeil(); maxGridPoint = maxGridPoint.getMultipliedComponents(spacing); minGridPoint.z = viewBox.getCorner1().z; maxGridPoint.z = viewBox.getCorner2().z; gridBox = RBox(minGridPoint, maxGridPoint); minGridPoint = viewBox.getCorner1(); minGridPoint = minGridPoint.getDividedComponents(metaSpacing).getFloor(); minGridPoint = minGridPoint.getMultipliedComponents(metaSpacing); maxGridPoint = viewBox.getCorner2(); maxGridPoint = maxGridPoint.getDividedComponents(metaSpacing).getCeil(); maxGridPoint = maxGridPoint.getMultipliedComponents(metaSpacing); minGridPoint.z = viewBox.getCorner1().z; maxGridPoint.z = viewBox.getCorner2().z; metaGridBox = RBox(minGridPoint, maxGridPoint); if (isometric) { QString i1 = RUnit::getLabel(spacing.x / cos(M_PI/6), *doc, true, true); QString i2 = RUnit::getLabel(metaSpacing.x / cos(M_PI/6) / 2, *doc, true, true); infoText = QString("%1 < %2").arg(i1).arg(i2); } else { QString i1 = RUnit::getLabel(spacing.x, *doc, true, true); QString i2 = RUnit::getLabel(metaSpacing.x, *doc, true, true); infoText = QString("%1 < %2").arg(i1).arg(i2); } }
void RExporter::exportLine(const RLine& line, double offset) { if (!line.isValid()) { return; } double length = line.getLength(); if (length>1e100 || length<RS::PointTolerance) { return; } RLinetypePattern p = getLinetypePattern(); // continuous line or // we are in draft mode or // QCAD is configured to show screen based line patterns if (!p.isValid() || p.getNumDashes() == 1 || draftMode || screenBasedLinetypes) { exportLineSegment(line); return; } p.scale(getPatternFactor()); double patternLength = p.getPatternLength(); // avoid huge number of small segments due to very fine // pattern or long lines: if (patternLength<RS::PointTolerance || length / patternLength > 5000) { exportLineSegment(line); return; } double angle = line.getAngle(); RVector* vp = NULL; vp = new RVector[p.getNumDashes()]; for (int i = 0; i < p.getNumDashes(); ++i) { vp[i] = RVector(cos(angle) * fabs(p.getDashLengthAt(i)), sin(angle) * fabs(p.getDashLengthAt(i))); } bool optimizeEnds = false; if (RMath::isNaN(offset)) { offset = getPatternOffset(length, p); optimizeEnds = true; } else { double num = ceil(offset / patternLength); offset -= num * patternLength; } bool done = false; int i = 0; RVector cursor(line.getStartPoint() + RVector::createPolar(offset, angle)); double total = offset; bool dashFound = false; bool gapFound = false; RVector p1 = line.getStartPoint(); RVector p2 = p1; do { if (dashFound && !gapFound) { // don't shoot over end of line: if (total + fabs(p.getDashLengthAt(i)) >= length - 1.0e-6) { if (optimizeEnds) { exportLineSegment(RLine(p1, line.endPoint)); } else { exportLineSegment(RLine(p1, p2)); } break; } exportLineSegment(RLine(p1, p2)); } // dash, no gap. note that a dash can have a length of 0.0 (point): if (p.getDashLengthAt(i) > -RS::PointTolerance) { // check if we're on the line already: if (total + p.getDashLengthAt(i) > 0) { p1 = cursor; // no gap at the beginning of the line: if (total < 0 || (!dashFound && optimizeEnds)) { p1 = line.startPoint; } p2 = cursor + vp[i]; if (!p2.equalsFuzzy(line.startPoint, 1.0e-6)) { dashFound = true; } } gapFound = false; } // gap: else { gapFound = true; } cursor += vp[i]; total += fabs(p.getDashLengthAt(i)); done = total > length; ++i; if (i >= p.getNumDashes()) { i = 0; } } while (!done); if (!gapFound || !dashFound) { if (total + fabs(p.getDashLengthAt(i)) >= length - 1.0e-6) { if (optimizeEnds || (total>length && !gapFound)) { exportLineSegment(RLine(p1, line.endPoint)); } else { exportLineSegment(RLine(p1, p2)); } } else { exportLineSegment(RLine(p1, p2)); } } delete[] vp; }
RVector TravelTimeDijkstraModelling::createDefaultStartModel() { return RVector(this->regionManager().parameterCount(), findMedianSlowness()); }
bool REntityData::scale(double scaleFactor, const RVector& center) { return scale(RVector(scaleFactor, scaleFactor, scaleFactor), center); }
bool RSolidEntity::setProperty(RPropertyTypeId propertyTypeId, const QVariant& value, RTransaction* transaction) { bool ret = REntity::setProperty(propertyTypeId, value, transaction); if (propertyTypeId==PropertyPoint1X || propertyTypeId==PropertyPoint1Y || propertyTypeId==PropertyPoint1Z) { RVector v = data.getVertexAt(0); if (propertyTypeId==PropertyPoint1X) { v.x = value.toDouble(); } else if (propertyTypeId==PropertyPoint1Y) { v.y = value.toDouble(); } else if (propertyTypeId==PropertyPoint1Z) { v.z = value.toDouble(); } data.setVertexAt(0, v); ret = true; } else if (propertyTypeId==PropertyPoint2X || propertyTypeId==PropertyPoint2Y || propertyTypeId==PropertyPoint2Z) { RVector v = data.getVertexAt(1); if (propertyTypeId==PropertyPoint2X) { v.x = value.toDouble(); } else if (propertyTypeId==PropertyPoint2Y) { v.y = value.toDouble(); } else if (propertyTypeId==PropertyPoint2Z) { v.z = value.toDouble(); } data.setVertexAt(1, v); ret = true; } else if (propertyTypeId==PropertyPoint3X || propertyTypeId==PropertyPoint3Y || propertyTypeId==PropertyPoint3Z) { RVector v = data.getVertexAt(2); if (propertyTypeId==PropertyPoint3X) { v.x = value.toDouble(); } else if (propertyTypeId==PropertyPoint3Y) { v.y = value.toDouble(); } else if (propertyTypeId==PropertyPoint3Z) { v.z = value.toDouble(); } data.setVertexAt(2, v); ret = true; } else if (propertyTypeId==PropertyPoint4X || propertyTypeId==PropertyPoint4Y || propertyTypeId==PropertyPoint4Z) { if (data.countVertices()<4) { data.appendVertex(RVector(0,0,0)); } RVector v = data.getVertexAt(3); if (propertyTypeId==PropertyPoint4X) { v.x = value.toDouble(); } else if (propertyTypeId==PropertyPoint4Y) { v.y = value.toDouble(); } else if (propertyTypeId==PropertyPoint4Z) { v.z = value.toDouble(); } data.setVertexAt(3, v); ret = true; } return ret; }
double RExporter::exportLine(const RLine& line, double offset) { double ret = RNANDOUBLE; if (!line.isValid()) { return ret; } double length = line.getLength(); if (length>1e100 || length<RS::PointTolerance) { return ret; } double angle = line.getAngle(); // continuous line or // we are in draft mode or // QCAD is configured to show screen based line patterns if (draftMode || screenBasedLinetypes || twoColorSelectedMode) { exportLineSegment(line, angle); return ret; } RLinetypePattern p = getLinetypePattern(); if (!p.isValid() || p.getNumDashes() <= 1) { exportLineSegment(line, angle); return ret; } p.scale(getLineTypePatternScale(p)); double patternLength = p.getPatternLength(); // avoid huge number of small segments due to very fine // pattern or long lines: if (patternLength<RS::PointTolerance || length / patternLength > RSettings::getDashThreshold()) { exportLineSegment(line, angle); return ret; } RVector* vp = NULL; vp = new RVector[p.getNumDashes()]; for (int i = 0; i < p.getNumDashes(); ++i) { vp[i] = RVector(cos(angle) * fabs(p.getDashLengthAt(i)), sin(angle) * fabs(p.getDashLengthAt(i))); } if (RMath::isNaN(offset)) { offset = p.getPatternOffset(length); } else { double num = ceil(offset / patternLength); offset -= num * patternLength; } bool done = false; int i = 0; RVector cursor(line.getStartPoint() + RVector::createPolar(offset, angle)); double total = offset; double nextTotal; bool isGap = false; RLine dash; do { double dashLength = p.getDashLengthAt(i); nextTotal = total + fabs(dashLength); //qDebug() << "total: " << total; //qDebug() << "nextTotal: " << nextTotal; // dash, no gap. note that a dash can have a length of 0.0 (point): if (dashLength > -RS::PointTolerance) { isGap = false; } // gap: else { isGap = true; } // check if we're on the line already // (since we might start before the line due to pattern offset): if (nextTotal > 0.0) { dash = RLine(cursor, cursor + vp[i]); if (!isGap) { // fist part is gap, then dash ret = -nextTotal; } else { // fist part is dash, then gap ret = nextTotal; } // shorten at start of line: if (total < 0.0 /*&& nextTotal > 0.0*/) { dash.startPoint = line.startPoint; ret = RNANDOUBLE; } // shorten at end of line: if (/*total < length &&*/ nextTotal >= length - 1.0e-6) { dash.endPoint = line.endPoint; ret = RINFDOUBLE; } if (!isGap) { exportLineSegment(dash, angle); ret = nextTotal; } } cursor += vp[i]; total = nextTotal; done = total > length; // export shape (zigzag, text, etc.) at end of dash / gap: if (p.hasShapeAt(i)) { QList<RPainterPath> pps = p.getShapeAt(i); exportLinetypeShape(pps, line, total, length, angle, cursor); } ++i; if (i >= p.getNumDashes()) { i = 0; } } while (!done); delete[] vp; return ret; }
RWheelEvent::RWheelEvent(const QWheelEvent& wheelEvent, RGraphicsScene& s, RGraphicsView& v) : QWheelEvent(wheelEvent), RInputEvent(RVector(wheelEvent.pos().x(), wheelEvent.pos().y()), s, v) { }
void RClipboardOperation::copy( RDocument& src, RDocument& dest, const RVector& offset, double scale, double rotation, bool flipHorizontal, bool flipVertical, bool toCurrentLayer, bool toCurrentBlock, bool overwriteLayers, bool overwriteBlocks, const QString& blockName, const QString& layerName, RTransaction& transaction, bool selectionOnly, bool clear, bool toModelSpaceBlock, bool preview, const RQMapQStringQString& attributes) const { bool overwriteLinetypes = false; double unitScale; if (src.getUnit()==RS::None) { unitScale = 1.0; } else { unitScale = RUnit::convert(1.0, src.getUnit(), dest.getUnit()); } if (clear) { dest.clear(); } QSet<REntity::Id> entityIdsSet; if (selectionOnly) { entityIdsSet = src.querySelectedEntities(); } else { entityIdsSet = src.queryAllEntities(); } QList<REntity::Id> entityIdsList = src.getStorage().orderBackToFront(entityIdsSet); // Non-const offset. reset to 0/0/0 if copying to block // (offset implemented as block reference offset). RVector off = offset; bool hasBlock = false; QSet<REntity::Id> attributeIds; // this part is used to insert ('paste') blocks from the part library // as new blocks: QSharedPointer<RBlockReferenceEntity> refp; if (!blockName.isNull()) { QSharedPointer<RBlock> block; hasBlock = dest.hasBlock(blockName); // block does not exist in dest - or - // block exists in dest and must be overwritten: if (!hasBlock || overwriteBlocks) { block = QSharedPointer<RBlock> (new RBlock(&dest, blockName, RVector(0, 0, 0))); transaction.overwriteBlock(block); } // block exists and must not be overwritten: else { block = dest.queryBlock(blockName); } Q_ASSERT(!block.isNull()); // create new block reference that references new, overwritten or existing block // (insert later, when block is complete, so we have bounding box for spatial index): RBlockReferenceEntity* ref = new RBlockReferenceEntity(&dest, RBlockReferenceData(block->getId(), RVector(0,0,0), RVector(1.0, 1.0, 1.0), 0.0)); refp = QSharedPointer<RBlockReferenceEntity>(ref); refp->setBlockId(dest.getCurrentBlockId()); off = RVector(0, 0, 0); if (flipHorizontal) { refp->flipHorizontal(); } if (flipVertical) { refp->flipVertical(); } //ref->scale(scale * unitScale); refp->scale(scale); refp->rotate(rotation); refp->move(offset); // create attribute for each attribute definition in block with // invalid parent ID (fixed later, when block reference ID is known): QSet<REntity::Id> ids = src.queryAllEntities(); QSet<REntity::Id>::iterator it; for (it=ids.begin(); it!=ids.end(); it++) { REntity::Id id = *it; QSharedPointer<RAttributeDefinitionEntity> attDef = src.queryEntity(id).dynamicCast<RAttributeDefinitionEntity>(); if (attDef.isNull()) { continue; } QSharedPointer<RAttributeEntity> att( new RAttributeEntity( &dest, RAttributeData(attDef->getData(), REntity::INVALID_ID, attDef->getTag()) ) ); att->scale(unitScale); refp->applyTransformationTo(*att); // assign values to attributes: QString tag = att->getTag(); if (attributes.contains(tag)) { att->setText(attributes[tag]); } // make sure the attribute has the correct layer ID of the // corresponding layer in dest: QSharedPointer<RLayer> destLayer = copyEntityLayer(*attDef, src, dest, overwriteLayers, transaction); att->setLayerId(destLayer->getId()); QSharedPointer<RLinetype> destLinetype = copyEntityLinetype(*attDef, src, dest, overwriteLinetypes, transaction); att->setLinetypeId(destLinetype->getId()); transaction.addObject(att, false); attributeIds.insert(att->getId()); } scale = 1.0; rotation = 0.0; flipHorizontal = false; flipVertical = false; toCurrentLayer = false; //toCurrentBlock = false; } // copy entities from src to dest: // if the block existed already in dest and is not overwritten, // there's nothing to do here: if (!hasBlock || overwriteBlocks || preview) { copiedLayers.clear(); copiedLinetypes.clear(); copiedBlocks.clear(); int counter = 0; QList<REntity::Id>::iterator it; for (it=entityIdsList.begin(); it!=entityIdsList.end(); ++it) { if (preview && ++counter>RSettings::getPreviewEntities()) { break; } QSharedPointer<REntity> entity = src.queryEntityDirect(*it); if (entity.isNull() || entity->isUndone()) { continue; } copyEntity( *entity.data(), src, dest, off, scale, unitScale, rotation, flipHorizontal, flipVertical, toCurrentLayer, toCurrentBlock, overwriteLayers, overwriteBlocks, blockName, transaction, toModelSpaceBlock // to model space: true for copy // (allow copy from inside any block definition), // false for paste ); } } // only overwrite layers: else if (overwriteLayers) { copiedLayers.clear(); int counter = 0; QList<REntity::Id>::iterator it; for (it=entityIdsList.begin(); it!=entityIdsList.end(); ++it) { if (preview && ++counter>RSettings::getPreviewEntities()) { break; } QSharedPointer<REntity> entity = src.queryEntityDirect(*it); if (entity.isNull() || entity->isUndone()) { continue; } copyEntityLayer( *entity.data(), src, dest, overwriteLayers, transaction ); } } // copying of entire block complete, insert block reference now since // we now have the bounding box for the spatial index: if (!refp.isNull()) { bool useCurrentAttributes = true; if (!layerName.isEmpty()) { useCurrentAttributes = false; refp->setLayerId(dest.getLayerId(layerName)); } transaction.addObject(refp, useCurrentAttributes); // fix parent ID of attributes created by the new inserted block: REntity::Id refId = refp->getId(); //QSet<REntity::Id> ids = dest.queryAllEntities(); QSet<REntity::Id>::iterator it; for (it=attributeIds.begin(); it!=attributeIds.end(); it++) { REntity::Id id = *it; QSharedPointer<RAttributeEntity> e = dest.queryEntityDirect(id).dynamicCast<RAttributeEntity>(); if (e.isNull()) { continue; } if (e->getParentId()==REntity::INVALID_ID) { e->setParentId(refId); } } } transaction.endCycle(); }
RMouseEvent::RMouseEvent(const QMouseEvent& mouseEvent, RGraphicsScene& s, RGraphicsView& v) : QMouseEvent(mouseEvent), RInputEvent(RVector(mouseEvent.posF().x(), mouseEvent.posF().y()), s, v) { }
QSharedPointer<RBlockReferenceEntity> RDimensionData::getDimensionBlockReference() const { QString dimBlockName = getDimBlockName(); if (dimBlockName.isEmpty()) { return QSharedPointer<RBlockReferenceEntity>(); } const RDocument* doc = getDocument(); if (doc==NULL) { return QSharedPointer<RBlockReferenceEntity>(); } RBlock::Id dimBlockId = doc->getBlockId(dimBlockName); // check if block is empty (ignore): if (!doc->hasBlockEntities(dimBlockId)) { return QSharedPointer<RBlockReferenceEntity>(); } // TODO: ignore block if dimension entity is valid (i.e. only use block if we cannot recompute (?)) RBlockReferenceEntity* dimBlockReference = new RBlockReferenceEntity((RDocument*)doc, RBlockReferenceData(dimBlockId, RVector(0,0), RVector(1,1), 0.0)/*, getId()*/); dimBlockReference->copyAttributesFrom(*this, true); //e.exportEntity(*dimBlockReference, preview, false, forceSelected); //delete dimBlockReference; return QSharedPointer<RBlockReferenceEntity>(dimBlockReference); }
/** * Exports a rectangle with the current attributes. * This is a convenience function that exports two triangles but may * also be re-implemented to do something else. */ void RExporter::exportRectangle(const RVector& p1, const RVector& p2) { exportQuad(p1, RVector(p2.x, p1.y), p2, RVector(p1.x, p2.y)); }
RVector RArc::getStartPoint() const { return RVector(center.x + cos(startAngle) * radius, center.y + sin( startAngle) * radius); }
RBox RCircle::getBoundingBox() const { return RBox(center - RVector(radius, radius), center + RVector(radius, radius)); }
RVector RArc::getEndPoint() const { return RVector(center.x + cos(endAngle) * radius, center.y + sin( endAngle) * radius); }