void OGRCompoundCurve::Value( double dfDistance, OGRPoint *poPoint ) const { if( dfDistance < 0 ) { StartPoint( poPoint ); return; } double dfLength = 0.0; for( int iGeom = 0; iGeom < oCC.nCurveCount; iGeom++ ) { const double dfSegLength = oCC.papoCurves[iGeom]->get_Length(); if( dfSegLength > 0 ) { if( (dfLength <= dfDistance) && ((dfLength + dfSegLength) >= dfDistance) ) { oCC.papoCurves[iGeom]->Value(dfDistance - dfLength, poPoint); return; } dfLength += dfSegLength; } } EndPoint( poPoint ); }
bool StatStore::recordStart(VERMONT::IpfixRecord::SourceID sourceId) { if (beginMonitoring != true) return false; packet_nb = byte_nb = 0; e_source = e_dest = EndPoint(IpAddress(0,0,0,0),0,0); return true; }
void USplineComponent::AddLoopEndpoint() { check(bClosedLoop); const int32 NumPoints = SplineInfo.Points.Num(); if (NumPoints > 0) { FInterpCurvePoint<FVector> EndPoint(SplineInfo.Points[0]); EndPoint.InVal = static_cast<float>(NumPoints); SplineInfo.Points.Add(EndPoint); } }
void Boundary2D::SetupBdry2D(::Bdry2D &bdry) const { int i=0; int iBdryPatch = 0; std::cerr << "Before Set size\n"; bdry.vSetSize (NumOfPatches(), NumOfPoints()); std::cerr << "Set size\n"; for (PointIterator p=FirstPoint(); p != EndPoint(); ++p, ++i) { bdry.vAddPoint((*p).coords()); bdry.vSetBdryPoint(i, false); } std::cerr << "Added points size\n"; for (PolylineIterator p=FirstPolyline(); p !=EndPolyline(); ++p) { SetupPolyline(bdry, *p, iBdryPatch); } std::cerr << "Added polylines size\n"; for (CircleIterator p=FirstCircle(); p !=EndCircle(); ++p) { SetupCircle(bdry, *p, iBdryPatch); } std::cerr << "Added circles size\n"; for (ArcIterator p=FirstArc(); p !=EndArc(); ++p) { SetupArc(bdry, *p, iBdryPatch); } std::cerr << "Added arcs size\n"; for (BezierIterator p=FirstBezier(); p !=EndBezier(); ++p) { SetupBezier(bdry, *p, iBdryPatch); } std::cerr << "Added beziers size\n"; for (SplineIterator p=FirstSpline(); p !=EndSpline(); ++p) { SetupSpline(bdry, *p, iBdryPatch); } std::cerr << "Added splines size\n"; bdry.vOrderConnectivityInfo(); // Find small angles bdry.vFindSmallAngles(); std::cerr << "Finished setupe\n"; }
void OGRLineString::Value( double dfDistance, OGRPoint * poPoint ) const { double dfLength = 0; int i; if( dfDistance < 0 ) { StartPoint( poPoint ); return; } for( i = 0; i < nPointCount-1; i++ ) { double dfDeltaX, dfDeltaY, dfSegLength; dfDeltaX = paoPoints[i+1].x - paoPoints[i].x; dfDeltaY = paoPoints[i+1].y - paoPoints[i].y; dfSegLength = sqrt(dfDeltaX*dfDeltaX + dfDeltaY*dfDeltaY); if (dfSegLength > 0) { if( (dfLength <= dfDistance) && ((dfLength + dfSegLength) >= dfDistance) ) { double dfRatio; dfRatio = (dfDistance - dfLength) / dfSegLength; poPoint->setX( paoPoints[i].x * (1 - dfRatio) + paoPoints[i+1].x * dfRatio ); poPoint->setY( paoPoints[i].y * (1 - dfRatio) + paoPoints[i+1].y * dfRatio ); if( getCoordinateDimension() == 3 ) poPoint->setZ( padfZ[i] * (1 - dfRatio) + padfZ[i] * dfRatio ); return; } dfLength += dfSegLength; } } EndPoint( poPoint ); }
int OGRCurve::get_IsClosed() const { OGRPoint oStartPoint, oEndPoint; StartPoint( &oStartPoint ); EndPoint( &oEndPoint ); if( oStartPoint.getX() == oEndPoint.getX() && oStartPoint.getY() == oEndPoint.getY() ) { return TRUE; } else { return FALSE; } }
void ON_Arc::Dump( ON_TextLog& dump ) const { dump.Print("Arc: normal = "); dump.Print(plane.zaxis); dump.Print(" center = "); dump.Print(plane.origin); dump.Print(" start = "); dump.Print( StartPoint() ); dump.Print(" end = "); dump.Print( EndPoint() ); dump.Print(" radius = "); dump.Print(Radius()); dump.Print(" angle = ["); dump.Print(m_angle[0]); dump.Print(","); dump.Print(m_angle[1]); dump.Print("]\n"); }
void SetStandard(Graph graph) { int elabel, adj_node, i, j; int u, v, currentedge; Edge edge; currentedge = U+2; for (i=1; i<=U; ++i) { edge = FirstEdge(graph,i); for (j = 1; j <= Degree(graph,i); ++j) { adj_node = EndPoint(edge); if (i < adj_node) { elabel = ELabel(edge)*2; WEIGHT[currentedge-1] = WEIGHT[currentedge] = 2*elabel; END[currentedge-1] = i; END[currentedge] = adj_node; if (A[i] == 0) A[i] = currentedge; else { u = i; v = A[i]; while (v != 0) { if (END[v] > adj_node) break; u = v; v = A[v]; } A[u] = currentedge; A[currentedge] = v; } u = adj_node; v = A[u]; while (v != 0) { u = v; v = A[v]; } A[u] = currentedge - 1; currentedge += 2; } edge = NextEdge(edge); } } }
DBmgr::DBmgr(const std::string& host, const uint16_t& port) : m_endpoint(EndPoint(host, port)) { int ret = m_endpoint.bind(); if ( ret == -1 ) { LOG4CPLUS_ERROR(LOGGER, "Bind socket failure, error code is[" << errno << "]"); throw std::runtime_error("Bind socket failure"); } m_endpoint.listen(10); ConfigureParser& config = SingletonConfigureParser::instance(); int size; if ( config.get("dbmgr", "threadPoolSize").empty() ) { LOG4CPLUS_WARN(LOGGER, "There is no threadPoolSize setted, use default 100"); size = 100; } else { size = config.getInt("dbmgr", "threadPoolSize"); } m_threadpool.create(size); }
bool TcpClient::ConnectToServer() { return ConnectToServer(EndPoint(boost::asio::ip::address::from_string(_serv_address), _serv_port)); }
C3DFileAdapter::OutputTables C3DFileAdapter::extendRead(const std::string& fileName) const { auto reader = btk::AcquisitionFileReader::New(); reader->SetFilename(fileName); reader->Update(); auto acquisition = reader->GetOutput(); EventTable event_table{}; auto events = acquisition->GetEvents(); for (auto it = events->Begin(); it != events->End(); ++it) { auto et = *it; event_table.push_back({ et->GetLabel(), et->GetTime(), et->GetFrame(), et->GetDescription() }); } OutputTables tables{}; auto marker_pts = btk::PointCollection::New(); for(auto it = acquisition->BeginPoint(); it != acquisition->EndPoint(); ++it) { auto pt = *it; if(pt->GetType() == btk::Point::Marker) marker_pts->InsertItem(pt); } if(marker_pts->GetItemNumber() != 0) { int marker_nrow = marker_pts->GetFrontItem()->GetFrameNumber(); int marker_ncol = marker_pts->GetItemNumber(); std::vector<double> marker_times(marker_nrow); SimTK::Matrix_<SimTK::Vec3> marker_matrix(marker_nrow, marker_ncol); std::vector<std::string> marker_labels{}; for (auto it = marker_pts->Begin(); it != marker_pts->End(); ++it) { marker_labels.push_back(SimTK::Value<std::string>((*it)->GetLabel())); } double time_step{1.0 / acquisition->GetPointFrequency()}; for(int f = 0; f < marker_nrow; ++f) { SimTK::RowVector_<SimTK::Vec3> row{ marker_pts->GetItemNumber(), SimTK::Vec3(SimTK::NaN) }; int m{0}; for(auto it = marker_pts->Begin(); it != marker_pts->End(); ++it) { auto pt = *it; // BTK reads empty values as zero, but sets a "residual" value // to -1 and it is how it knows to export these values as // blank, instead of 0, when exporting to .trc // See: BTKCore/Code/IO/btkTRCFileIO.cpp#L359-L360 // Read in value if it is not zero or residual is not -1 if (!pt->GetValues().row(f).isZero() || //not precisely zero (pt->GetResiduals().coeff(f) != -1) ) {//residual is not -1 row[m] = SimTK::Vec3{ pt->GetValues().coeff(f, 0), pt->GetValues().coeff(f, 1), pt->GetValues().coeff(f, 2) }; } ++m; } marker_matrix.updRow(f) = row; marker_times[f] = 0 + f * time_step; //TODO: 0 should be start_time } // Create the data auto marker_table = std::make_shared<TimeSeriesTableVec3>(marker_times, marker_matrix, marker_labels); marker_table-> updTableMetaData(). setValueForKey("DataRate", std::to_string(acquisition->GetPointFrequency())); marker_table-> updTableMetaData(). setValueForKey("Units", acquisition->GetPointUnit()); marker_table->updTableMetaData().setValueForKey("events", event_table); tables.emplace(_markers, marker_table); } // This is probably the right way to get the raw forces data from force // platforms. Extract the collection of force platforms. auto force_platforms_extractor = btk::ForcePlatformsExtractor::New(); force_platforms_extractor->SetInput(acquisition); auto force_platform_collection = force_platforms_extractor->GetOutput(); force_platforms_extractor->Update(); std::vector<SimTK::Matrix_<double>> fpCalMatrices{}; std::vector<SimTK::Matrix_<double>> fpCorners{}; std::vector<SimTK::Matrix_<double>> fpOrigins{}; std::vector<unsigned> fpTypes{}; auto fp_force_pts = btk::PointCollection::New(); auto fp_moment_pts = btk::PointCollection::New(); auto fp_position_pts = btk::PointCollection::New(); for(auto platform = force_platform_collection->Begin(); platform != force_platform_collection->End(); ++platform) { const auto& calMatrix = (*platform)->GetCalMatrix(); const auto& corners = (*platform)->GetCorners(); const auto& origins = (*platform)->GetOrigin(); fpCalMatrices.push_back(convertToSimtkMatrix(calMatrix)); fpCorners.push_back(convertToSimtkMatrix(corners)); fpOrigins.push_back(convertToSimtkMatrix(origins)); fpTypes.push_back(static_cast<unsigned>((*platform)->GetType())); // Get ground reaction wrenches for the force platform. auto ground_reaction_wrench_filter = btk::GroundReactionWrenchFilter::New(); ground_reaction_wrench_filter->setLocation( btk::GroundReactionWrenchFilter::Location(getLocationForForceExpression())); ground_reaction_wrench_filter->SetInput(*platform); auto wrench_collection = ground_reaction_wrench_filter->GetOutput(); ground_reaction_wrench_filter->Update(); for(auto wrench = wrench_collection->Begin(); wrench != wrench_collection->End(); ++wrench) { // Forces time series. fp_force_pts->InsertItem((*wrench)->GetForce()); // Moment time series. fp_moment_pts->InsertItem((*wrench)->GetMoment()); // Position time series. fp_position_pts->InsertItem((*wrench)->GetPosition()); } } if(fp_force_pts->GetItemNumber() != 0) { std::vector<std::string> labels{}; ValueArray<std::string> units{}; for(int fp = 1; fp <= fp_force_pts->GetItemNumber(); ++fp) { auto fp_str = std::to_string(fp); labels.push_back(SimTK::Value<std::string>("f" + fp_str)); auto force_unit = acquisition->GetPointUnits(). at(_unit_index.at("force")); units.upd().push_back(SimTK::Value<std::string>(force_unit)); labels.push_back(SimTK::Value<std::string>("p" + fp_str)); auto position_unit = acquisition->GetPointUnits(). at(_unit_index.at("marker")); units.upd().push_back(SimTK::Value<std::string>(position_unit)); labels.push_back(SimTK::Value<std::string>("m" + fp_str)); auto moment_unit = acquisition->GetPointUnits(). at(_unit_index.at("moment")); units.upd().push_back(SimTK::Value<std::string>(moment_unit)); } const int nf = fp_force_pts->GetFrontItem()->GetFrameNumber(); std::vector<double> force_times(nf); SimTK::Matrix_<SimTK::Vec3> force_matrix(nf, (int)labels.size()); double time_step{1.0 / acquisition->GetAnalogFrequency()}; for(int f = 0; f < nf; ++f) { SimTK::RowVector_<SimTK::Vec3> row{fp_force_pts->GetItemNumber() * 3}; int col{0}; for(auto fit = fp_force_pts->Begin(), mit = fp_moment_pts->Begin(), pit = fp_position_pts->Begin(); fit != fp_force_pts->End(); ++fit, ++mit, ++pit) { row[col] = SimTK::Vec3{(*fit)->GetValues().coeff(f, 0), (*fit)->GetValues().coeff(f, 1), (*fit)->GetValues().coeff(f, 2)}; ++col; row[col] = SimTK::Vec3{(*pit)->GetValues().coeff(f, 0), (*pit)->GetValues().coeff(f, 1), (*pit)->GetValues().coeff(f, 2)}; ++col; row[col] = SimTK::Vec3{(*mit)->GetValues().coeff(f, 0), (*mit)->GetValues().coeff(f, 1), (*mit)->GetValues().coeff(f, 2)}; ++col; } force_matrix.updRow(f) = row; force_times[f] = 0 + f * time_step; //TODO: 0 should be start_time } auto& force_table = *(new TimeSeriesTableVec3(force_times, force_matrix, labels)); TimeSeriesTableVec3::DependentsMetaData force_dep_metadata = force_table.getDependentsMetaData(); // add units to the dependent meta data force_dep_metadata.setValueArrayForKey("units", units); force_table.setDependentsMetaData(force_dep_metadata); force_table. updTableMetaData(). setValueForKey("CalibrationMatrices", std::move(fpCalMatrices)); force_table. updTableMetaData(). setValueForKey("Corners", std::move(fpCorners)); force_table. updTableMetaData(). setValueForKey("Origins", std::move(fpOrigins)); force_table. updTableMetaData(). setValueForKey("Types", std::move(fpTypes)); force_table. updTableMetaData(). setValueForKey("DataRate", std::to_string(acquisition->GetAnalogFrequency())); tables.emplace(_forces, std::shared_ptr<TimeSeriesTableVec3>(&force_table)); force_table.updTableMetaData().setValueForKey("events", event_table); } return tables; }
fixed GeoVector::MinimumDistance(const GeoPoint &source, const GeoPoint &ref) const { return ::CrossTrackError(source, EndPoint(source), ref, NULL); }
GeoPoint GeoVector::IntermediatePoint(const GeoPoint &source, const fixed distance) const { return source.IntermediatePoint(EndPoint(source), distance); }
C3DFileAdapter::OutputTables C3DFileAdapter::extendRead(const std::string& fileName) const { auto reader = btk::AcquisitionFileReader::New(); reader->SetFilename(fileName); reader->Update(); auto acquisition = reader->GetOutput(); OutputTables tables{}; auto& marker_table = *(new TimeSeriesTableVec3{}); auto& force_table = *(new TimeSeriesTableVec3{}); tables.emplace(_markers, std::shared_ptr<TimeSeriesTableVec3>(&marker_table)); tables.emplace(_forces, std::shared_ptr<TimeSeriesTableVec3>(&force_table)); auto marker_pts = btk::PointCollection::New(); for(auto it = acquisition->BeginPoint(); it != acquisition->EndPoint(); ++it) { auto pt = *it; if(pt->GetType() == btk::Point::Marker) marker_pts->InsertItem(pt); } if(marker_pts->GetItemNumber() != 0) { marker_table. updTableMetaData(). setValueForKey("DataRate", std::to_string(acquisition->GetPointFrequency())); marker_table. updTableMetaData(). setValueForKey("Units", acquisition->GetPointUnit()); ValueArray<std::string> marker_labels{}; for(auto it = marker_pts->Begin(); it != marker_pts->End(); ++it) { marker_labels. upd(). push_back(SimTK::Value<std::string>((*it)->GetLabel())); } TimeSeriesTableVec3::DependentsMetaData marker_dep_metadata{}; marker_dep_metadata.setValueArrayForKey("labels", marker_labels); marker_table.setDependentsMetaData(marker_dep_metadata); double time_step{1.0 / acquisition->GetPointFrequency()}; for(int f = 0; f < marker_pts->GetFrontItem()->GetFrameNumber(); ++f) { SimTK::RowVector_<SimTK::Vec3> row{marker_pts->GetItemNumber()}; int m{0}; for(auto it = marker_pts->Begin(); it != marker_pts->End(); ++it) { auto pt = *it; row[m++] = SimTK::Vec3{pt->GetValues().coeff(f, 0), pt->GetValues().coeff(f, 1), pt->GetValues().coeff(f, 2)}; } marker_table.appendRow(0 + f * time_step, row); } } // This is probably the right way to get the raw forces data from force // platforms. Extract the collection of force platforms. auto force_platforms_extractor = btk::ForcePlatformsExtractor::New(); force_platforms_extractor->SetInput(acquisition); auto force_platform_collection = force_platforms_extractor->GetOutput(); force_platforms_extractor->Update(); std::vector<SimTK::Matrix_<double>> fpCalMatrices{}; std::vector<SimTK::Matrix_<double>> fpCorners{}; std::vector<SimTK::Matrix_<double>> fpOrigins{}; std::vector<unsigned> fpTypes{}; auto fp_force_pts = btk::PointCollection::New(); auto fp_moment_pts = btk::PointCollection::New(); auto fp_position_pts = btk::PointCollection::New(); for(auto platform = force_platform_collection->Begin(); platform != force_platform_collection->End(); ++platform) { const auto& calMatrix = (*platform)->GetCalMatrix(); const auto& corners = (*platform)->GetCorners(); const auto& origins = (*platform)->GetOrigin(); fpCalMatrices.push_back(convertToSimtkMatrix(calMatrix)); fpCorners.push_back(convertToSimtkMatrix(corners)); fpOrigins.push_back(convertToSimtkMatrix(origins)); fpTypes.push_back(static_cast<unsigned>((*platform)->GetType())); // Get ground reaction wrenches for the force platform. auto ground_reaction_wrench_filter = btk::GroundReactionWrenchFilter::New(); ground_reaction_wrench_filter->SetInput(*platform); auto wrench_collection = ground_reaction_wrench_filter->GetOutput(); ground_reaction_wrench_filter->Update(); for(auto wrench = wrench_collection->Begin(); wrench != wrench_collection->End(); ++wrench) { // Forces time series. fp_force_pts->InsertItem((*wrench)->GetForce()); // Moment time series. fp_moment_pts->InsertItem((*wrench)->GetMoment()); // Position time series. fp_position_pts->InsertItem((*wrench)->GetPosition()); } } //shrik<btk::ForcePlatform::Origin> foo; if(fp_force_pts->GetItemNumber() != 0) { force_table. updTableMetaData(). setValueForKey("CalibrationMatrices", std::move(fpCalMatrices)); force_table. updTableMetaData(). setValueForKey("Corners", std::move(fpCorners)); force_table. updTableMetaData(). setValueForKey("Origins", std::move(fpOrigins)); force_table. updTableMetaData(). setValueForKey("Types", std::move(fpTypes)); force_table. updTableMetaData(). setValueForKey("DataRate", std::to_string(acquisition->GetAnalogFrequency())); ValueArray<std::string> labels{}; ValueArray<std::string> units{}; for(int fp = 1; fp <= fp_force_pts->GetItemNumber(); ++fp) { auto fp_str = std::to_string(fp); labels.upd().push_back(SimTK::Value<std::string>("f" + fp_str)); auto force_unit = acquisition->GetPointUnits(). at(_unit_index.at("force")); units.upd().push_back(SimTK::Value<std::string>(force_unit)); labels.upd().push_back(SimTK::Value<std::string>("m" + fp_str)); auto moment_unit = acquisition->GetPointUnits(). at(_unit_index.at("moment")); units.upd().push_back(SimTK::Value<std::string>(moment_unit)); labels.upd().push_back(SimTK::Value<std::string>("p" + fp_str)); auto position_unit = acquisition->GetPointUnits(). at(_unit_index.at("marker")); units.upd().push_back(SimTK::Value<std::string>(position_unit)); } TimeSeriesTableVec3::DependentsMetaData force_dep_metadata{}; force_dep_metadata.setValueArrayForKey("labels", labels); force_dep_metadata.setValueArrayForKey("units", units); force_table.setDependentsMetaData(force_dep_metadata); double time_step{1.0 / acquisition->GetAnalogFrequency()}; for(int f = 0; f < fp_force_pts->GetFrontItem()->GetFrameNumber(); ++f) { SimTK::RowVector_<SimTK::Vec3> row{fp_force_pts->GetItemNumber() * 3}; int col{0}; for(auto fit = fp_force_pts->Begin(), mit = fp_moment_pts->Begin(), pit = fp_position_pts->Begin(); fit != fp_force_pts->End(); ++fit, ++mit, ++pit) { row[col] = SimTK::Vec3{(*fit)->GetValues().coeff(f, 0), (*fit)->GetValues().coeff(f, 1), (*fit)->GetValues().coeff(f, 2)}; ++col; row[col] = SimTK::Vec3{(*mit)->GetValues().coeff(f, 0), (*mit)->GetValues().coeff(f, 1), (*mit)->GetValues().coeff(f, 2)}; ++col; row[col] = SimTK::Vec3{(*pit)->GetValues().coeff(f, 0), (*pit)->GetValues().coeff(f, 1), (*pit)->GetValues().coeff(f, 2)}; ++col; } force_table.appendRow(0 + f * time_step, row); } } EventTable event_table{}; auto events = acquisition->GetEvents(); for(auto it = events->Begin(); it != events->End(); ++it) { auto et = *it; event_table.push_back({et->GetLabel(), et->GetTime(), et->GetFrame(), et->GetDescription()}); } marker_table.updTableMetaData().setValueForKey("events", event_table); force_table.updTableMetaData().setValueForKey("events", event_table); return tables; }
EndPoint GetIPEndPoint(char const* ip, short port) { return (EndPoint(net::ADDR_INET6, ip, port)); }
EndPoint GetAnyIPEndPoint(short port) { return (EndPoint(net::ADDR_INET6, NULL, port)); }
double GeoVector::MinimumDistance(const GeoPoint &source, const GeoPoint &ref) const { return ::CrossTrackError(source, EndPoint(source), ref, nullptr); }
BOOL FreeHandEPSFilter::ProcessToken() { // Decode the command, and execute it... switch (Token) { // state saving case EPSC_vms: if(!Import_gsave()) return FALSE; break; case EPSC_vmr: if(!Import_grestore()) return FALSE; break; case EPSC_vmrs: if(!Import_grestore()) return FALSE; if(!Import_gsave()) return FALSE; break; // tokens to ignore case EPSC_FREEHAND_IGNOREDTOKEN: break; // tokens which should be ignored and one entry discarded case EPSC_load: // the load part of a fill - discard the /clipper before it case EPSC_fhsetspreadallow: if(!Stack.Discard(1)) goto EPSError; break; case EPSC_concat: if(!Stack.DiscardArray()) goto EPSError; break; // complex paths... case EPSC_eomode: { INT32 ComplexStart; if(!Stack.Pop(&ComplexStart)) goto EPSError; // is this a start of a complex path? if(ComplexStart != TRUE) { ComplexPathMode = FALSE; } else { HadFirstOfComplexPath = FALSE; ComplexPathMode = TRUE; } } break; case EPSC_true: Stack.Push((INT32)TRUE); break; case EPSC_false: Stack.Push((INT32)FALSE); break; case EPSC_u: HadFirstOfComplexPath = FALSE; return EPSFilter::ProcessToken(); break; // colours case EPSC_Ka: case EPSC_ka: { DocColour Colour; if(PopColour(&Colour)) { // Remember this colour for future objects if (Token == EPSC_ka) { if (!SetFillColour(Colour)) goto NoMemory; } else { if (!SetLineColour(Colour)) goto NoMemory; } } else // Invalid colour operands goto EPSError; } break; case EPSC_Xa: case EPSC_xa: { DocColour Colour; if(PopNamedColour(&Colour)) { // Remember this colour for future objects if (Token == EPSC_xa) { if (!SetFillColour(Colour)) goto NoMemory; } else { if (!SetLineColour(Colour)) goto NoMemory; } } else // Invalid colour operands goto EPSError; } break; case EPSC_H: if(ComplexPathMode) { // in complex path mode - make this a filled one, not a discarded one Token = EPSC_S; } return EPSFilter::ProcessToken(); break; case EPSC_h: if(ComplexPathMode) { // in complex path mode - modify and process Token = EPSC_s; return EPSFilter::ProcessToken(); break; } // the hidden path closing operator - a grad fill thingy will follow shortly maybe... // this will prevent it being processed now, although it may get processed later on. HadhToken = TRUE; break; // for clipping masks, do some funky stuff case EPSC_q: // if there's a pending grad fill... if(DoingGradFill) { if(pPath != 0) { // right then, make a copy of the path... NodePath *pPathClone; if(!pPath->NodeCopy((Node **)&pPathClone)) { goto NoMemory; } // copy the flags EPSFlagsDefn EPSFlagsClone = EPSFlags; // send a token to finish and fill the path... Token = (pInkPath->IsFilled)?EPSC_f:EPSC_s; if(!EPSFilter::ProcessToken()) return FALSE; // restore the old fill if(!RestoreCurrentFill()) goto NoMemory; // restore the copy of the path pPath = pPathClone; pInkPath = &pPath->InkPath; // restore the flags EPSFlags = EPSFlagsClone; // definately want to send an h HadhToken = TRUE; } // done the grad fill DoingGradFill = FALSE; // restore the old token Token = EPSC_q; } // clipping started - have we got an h token to send? if(HadhToken) FHEF_SENDh // process this return EPSFilter::ProcessToken(); break; // for now, if there's no path, don't return a W case EPSC_W: if(pPath == 0) { // OK, now we want to get the last path we created, make a copy of it and then install it as the current one if(pLastPathSeen == 0) goto EPSError; // make a copy of it NodePath *pClone; if(!pLastPathSeen->NodeCopy((Node **)&pClone)) goto NoMemory; // delete it's attributes pClone->DeleteChildren(pClone->FindFirstChild()); // make it the current path pPath = pClone; pInkPath = &pPath->InkPath; ThePathType = PATH_NORMAL; EPSFlags.NoAttributes = TRUE; } if(pPath != 0) return EPSFilter::ProcessToken(); break; // we may need to modify path closing things if we're doing a grad fill case EPSC_s: case EPSC_S: if(Token == EPSC_S) { // if we've had an h token but no grad fill, send the h now if(HadhToken) FHEF_SENDh // if we've got a grad fill, modify the token we got if(DoingGradFill) Token = EPSC_b; } // process the possily modified token normally HadhToken = FALSE; return EPSFilter::ProcessToken(); break; // modify path closing for grad fills. case EPSC_n: if(DoingGradFill) { Token = EPSC_f; // we want to fill the thing HadhToken = FALSE; return EPSFilter::ProcessToken(); break; } HadhToken = FALSE; // ignore h's as this is another end path thingy... if(pPath != 0) return EPSFilter::ProcessToken(); break; // unset the had h token for other path closing things case EPSC_N: case EPSC_F: case EPSC_f: case EPSC_B: case EPSC_b: HadhToken = FALSE; return EPSFilter::ProcessToken(); break; // interested in path element things to switch off grad fills case EPSC_m: if(InText) { // if we're doing some text, discard the moveto command if(!Stack.Discard(2)) goto EPSError; break; } case EPSC_l: case EPSC_L: case EPSC_c: case EPSC_C: case EPSC_v: case EPSC_V: case EPSC_y: case EPSC_Y: // maybe we need an h token to be sent if(HadhToken) FHEF_SENDh // stop grad fill if(DoingGradFill) { // turn the grad fill state off DoingGradFill = FALSE; // restore the old fill type RestoreCurrentFill(); } return EPSFilter::ProcessToken(); break; case EPSC_recfill: { // get the colours DocColour StartColour, EndColour; if(!PopColour(&EndColour) || !PopColour(&StartColour)) goto EPSError; // discard the fill type thingy - we can only do colours if(!DiscardFillSubType()) goto EPSError; // OK, now a few coords DocCoord Centre; double Angle; DocRect BBox; if(!Stack.PopCoordPair(&BBox.hi) || !Stack.PopCoordPair(&BBox.lo) || !Stack.Pop(&Angle) || !Stack.PopCoordPair(&Centre)) goto EPSError; // munge the angle a little and get it into radians Angle += 225; Angle = (Angle * (2 * PI)) / 360; // see if we can get a more accurate BBox if(pPath != 0) { BBox = pPath->GetBoundingRect(); Centre.x = BBox.lo.x + (BBox.Width() / 2); Centre.y = BBox.lo.y + (BBox.Height() / 2); } // OK, we've got all the stuff we need to do some niceness on it BBox.Translate(0 - Centre.x, 0 - Centre.y); DocCoord StartPoint, EndPoint; StartPoint.x = Centre.x + (INT32)(((double)BBox.lo.x * cos(Angle)) - ((double)BBox.lo.y * sin(Angle))); StartPoint.y = Centre.y + (INT32)(((double)BBox.lo.x * sin(Angle)) + ((double)BBox.lo.y * cos(Angle))); EndPoint.x = Centre.x + (INT32)(((double)BBox.hi.x * cos(Angle)) - ((double)BBox.hi.y * sin(Angle))); EndPoint.y = Centre.y + (INT32)(((double)BBox.hi.x * sin(Angle)) + ((double)BBox.hi.y * cos(Angle))); // store current fill attribute SaveCurrentFill(); // set the fill if(!SetLinearFill(StartColour, EndColour, StartPoint, EndPoint)) goto NoMemory; // say we're doing a grad fill DoingGradFill = TRUE; HadhToken = FALSE; // absorb this } break; case EPSC_radfill: { // get the colours DocColour StartColour, EndColour; if(!PopColour(&StartColour) || !PopColour(&EndColour)) goto EPSError; // get the radius and centre coordinate DocCoord Centre; INT32 Radius; if(!Stack.PopCoord(&Radius) || !Stack.PopCoordPair(&Centre)) goto EPSError; // store current fill attribute SaveCurrentFill(); // set the fill DocCoord EndPoint(Centre.x + Radius, Centre.y); if(!SetRadialFill(StartColour, EndColour, Centre, EndPoint)) goto NoMemory; // say we're doing a grad fill DoingGradFill = TRUE; HadhToken = FALSE; } break; case EPSC_BeginSetup: // there's probably a colour list or something in that there setup thingy - search for the spots token { BOOL Found = FALSE; while(Found == FALSE) { if(!EPSFile->GetToken()) return FALSE; if(EPSFile->GetTokenType() == TOKEN_NORMAL) { if(camStrcmp(TokenBuf, _T("spots")) == 0) { // check to see if the array is about to start if(!EPSFile->GetToken()) return FALSE; if(TokenBuf[0] == '[') { TRACEUSER( "Ben", _T("Found spots\n")); Found = TRUE; } } } if(camStrncmp(TokenBuf, _T("%%EndSetup"), 10) == 0) { TRACEUSER( "Ben", _T("Met end of setup without finding spots\n")); break; } if(EPSFile->eof()) goto EPSError; } if(Found == TRUE) { InColours = TRUE; } } break; case EPSC_def: if(InColours) { // finished the colours... TRACEUSER( "Ben", _T("Finished spot colours\n")); // scan for the end of the setup section BOOL Found = FALSE; while(Found == FALSE) { if(!EPSFile->GetToken()) return FALSE; if(EPSFile->GetTokenType() == TOKEN_COMMENT) { if(camStrncmp(TokenBuf, _T("%%EndSetup"), 10) == 0) { TRACEUSER( "Ben", _T("Found end of setup\n")); Found = TRUE; } } if(EPSFile->eof()) goto EPSError; } // get the ] off the stack EPSCommand Ignored; Stack.PopCmd(&Ignored); // empty it... Stack.DeleteAll (); InColours = FALSE; } else { // probably a font type thingy - empty the stack including commands Stack.DeleteAll (); } break; case EPSC_newcmykcustomcolor: // OK, here's a named colour... add it to those known { // discard some random thingy if(!Stack.Discard()) goto EPSError; // get the name String_64 ColourName; if(!Stack.Pop(&ColourName)) goto EPSError; // get the components double C, M, Y, K; if(!Stack.Pop(&K) || !Stack.Pop(&Y) || !Stack.Pop(&M) || !Stack.Pop(&C)) goto EPSError; // make the new colour ColourCMYK Colour; Colour.Cyan = C; Colour.Magenta = M; Colour.Yellow = Y; Colour.Key = K; // add it if(!pNewColours->AddColour(&ColourName, &Colour)) goto NoMemory; // add it to the list of colours // this is a bit of a bodge, but never mind. Shouldn't be that bad. IndexedColour *TheNewColour = pNewColours->GetColour(ColourName); if(TheNewColour == 0) goto NoMemory; // add it to the list of colours // enough space? if((ColourArrayEntries + 1) >= ColourArraySize) { TRACEUSER( "Ben", _T("Extening colour array\n")); IndexedColour **NewPtr = (IndexedColour **)CCRealloc(ColourArray, (ColourArraySize + FHEF_COLOURARRAY_CHUNK) * sizeof(IndexedColour *)); if(NewPtr == 0) goto NoMemory; ColourArray = NewPtr; ColourArraySize += FHEF_COLOURARRAY_CHUNK; } // add ColourArray[ColourArrayEntries] = TheNewColour; ColourArrayEntries++; } break; // ignore text stuff case EPSC_makesetfont: if(!Stack.DiscardArray()) goto EPSError; if(!Stack.Discard(1)) goto EPSError; InText = TRUE; break; case EPSC_ts: if(!Stack.Discard(6)) goto EPSError; break; case EPSC_stob: case EPSC_sts: Stack.DeleteAll (); InText = FALSE; break; default: // Token not understood - pass on to base class return EPSFilter::ProcessToken(); } // No errors encountered while parsing this token and its operands. return TRUE; // Error handlers: EPSError: HandleEPSError(); return FALSE; NoMemory: HandleNoMemory(); return FALSE; }
// grayman #3584 - rewritten for light cones EIntersection IntersectLineLightCone(const idVec3 rkLine[LSG_COUNT], idVec3 rkCone[ELC_COUNT], idVec3 Intersect[2], bool inside[2]) { EIntersection rc = INTERSECT_COUNT; int i, n, intersectionCount, x; float t; idPlane lightProject[4]; idPlane frustum[6]; int sides[6][2] = { {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} }; int sidesBack = 0; idStr txt; idStr format("Frustum[%u]"); idVec3 EndPoint(rkLine[LSG_ORIGIN]+rkLine[LSG_DIRECTION]); DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING(" rkLine[LSG_ORIGIN] = [%s]\r", rkLine[LSG_ORIGIN].ToString()); DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING(" rkLine[LSG_DIRECTION] = [%s]\r", rkLine[LSG_DIRECTION].ToString()); DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING(" EndPoint = [%s]\r", EndPoint.ToString()); R_SetLightProject(lightProject, rkCone[ELC_ORIGIN], rkCone[ELA_TARGET], rkCone[ELA_RIGHT], rkCone[ELA_UP], rkCone[ELA_START], rkCone[ELA_END]); R_SetLightFrustum(lightProject, frustum); /* DM_LOGPLANE(LC_MATH, LT_DEBUG, "Light[0]", lightProject[0]); DM_LOGPLANE(LC_MATH, LT_DEBUG, "Light[1]", lightProject[1]); DM_LOGPLANE(LC_MATH, LT_DEBUG, "Light[2]", lightProject[2]); DM_LOGPLANE(LC_MATH, LT_DEBUG, "Light[3]", lightProject[3]); */ n = format.Length(); // grayman #3584 - determine whether the start and end points of the line segment // lie on the back (inside) or front (outside) of each of the 6 planes of the light cone intersectionCount = 0; for ( i = 0 ; i < 6 ; i++ ) { sprintf(txt, format, i); DM_LOGPLANE(LC_MATH, LT_DEBUG, txt, frustum[i]); sides[i][0] = frustum[i].Side(rkLine[LSG_ORIGIN], idMath::FLT_EPSILON); sides[i][1] = frustum[i].Side(EndPoint, idMath::FLT_EPSILON); DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Frustum[%d]: sides[%d][0]: %d sides[%d][1]: %d\r", i, i,sides[i][0], i,sides[i][1]); if ( ( sides[i][0] == PLANESIDE_FRONT ) && ( sides[i][1] == PLANESIDE_FRONT ) ) { // both ends of the line are outside the frustum, no need to calculate an intersection inside[0] = false; inside[1] = false; return INTERSECT_OUTSIDE; } if ( sides[i][0] == PLANESIDE_BACK ) { sidesBack++; } if ( sides[i][1] == PLANESIDE_BACK ) { sidesBack++; } } if ( sidesBack == 12 ) { // both ends of the line are inside the frustum, no need to calculate an intersection rc = INTERSECT_NONE; Intersect[0] = rkLine[LSG_ORIGIN]; Intersect[1] = EndPoint; inside[0] = true; inside[1] = true; } else // calculate an intersection { // We've determined that at least one of the endpoints is possibly inside // the frustum (light volume). for ( i = 0 ; i < 6 ; i++ ) { if ( sides[i][0] != sides[i][1] ) { // the line crosses the plane, so calculate an intersection if ( frustum[i].RayIntersection(rkLine[LSG_ORIGIN], rkLine[LSG_DIRECTION], t) ) // grayman #3584 //if (frustum[i].LineIntersection(rkLine[LSG_ORIGIN], rkLine[LSG_DIRECTION], &t) == true) // grayman #3584 - this call gives wrong answers { idVec3 candidate = rkLine[LSG_ORIGIN] + t*rkLine[LSG_DIRECTION]; // This intersection is valid iff it lies on the backside of all planes. // So check that, except for the plane you just intersected, because // you know that will return INTERSECT_ON, which is okay. bool inside = true; for ( int j = 0 ; j < 6 ; j++ ) { if ( j == i ) { continue; // skip the plane you just intersected } x = frustum[j].Side(candidate, idMath::FLT_EPSILON); if (x == PLANESIDE_FRONT) { inside = false; break; // no need to continue, since the point is outside } } if ( inside ) { // This is a valid intersection point. Intersect[intersectionCount] = candidate; DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Frustum[%u] intersects\r", i); if (++intersectionCount > 1) { break; } } } } } if ( intersectionCount == 0 ) { // both ends of the line are outside the frustum, no need to calculate an intersection rc = INTERSECT_OUTSIDE; inside[0] = false; inside[1] = false; } else if ( intersectionCount == 1 ) { // One end of the line segment is inside the cone, and the other outside. rc = INTERSECT_PARTIAL; // Need to determine which end of the line is inside. It will be // the second of the two points returned. The first point will be // the intersection, and it has already been filled in (Intersect[0]). // Check the results of the side checks. If sides[0..6][0] are all // PLANESIDE_BACK, then the line origin is inside. // Otherwise, the line end is inside Intersect[1] = rkLine[LSG_ORIGIN]; // assume it's the line origin inside[0] = true; inside[1] = false; for ( i = 0 ; i < 6 ; i++ ) { if (sides[i][0] == PLANESIDE_FRONT ) { Intersect[1] = EndPoint; // nope, it must be the line end inside[0] = false; inside[1] = true; break; } } } else // intersectionCount == 2 { rc = INTERSECT_FULL; inside[0] = false; inside[1] = false; /* // old code bool bStart = true; bool bEnd = true; for ( i = 0 ; i < 6 ; i++ ) { x = frustum[i].Side(Intersect[0], idMath::FLT_EPSILON); DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Frustum[%u/0] intersection test returns %u\r", i, x); if (x != PLANESIDE_BACK) { bStart = false; } x = frustum[i].Side(Intersect[1], idMath::FLT_EPSILON); DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Frustum[%u/1] intersection test returns %u\r", i, x); if (x != PLANESIDE_BACK) { bEnd = false; } } if (bStart == false && bEnd == false) { rc = INTERSECT_OUTSIDE; }*/ } } DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Intersection count = %u\r", intersectionCount); DM_LOGVECTOR3(LC_MATH, LT_DEBUG, "Intersect[0]", Intersect[0]); DM_LOGVECTOR3(LC_MATH, LT_DEBUG, "Intersect[1]", Intersect[1]); return rc; }
DBmgrTask::DBmgrTask(const int& fd) : m_client(EndPoint(fd)) { }
void OGRCircularString::Value( double dfDistance, OGRPoint * poPoint ) const { if( dfDistance < 0 ) { StartPoint( poPoint ); return; } double dfLength = 0; for( int i = 0; i < nPointCount - 2; i += 2 ) { const double x0 = paoPoints[i].x; const double y0 = paoPoints[i].y; const double x1 = paoPoints[i+1].x; const double y1 = paoPoints[i+1].y; const double x2 = paoPoints[i+2].x; const double y2 = paoPoints[i+2].y; double R = 0.0; double cx = 0.0; double cy = 0.0; double alpha0 = 0.0; double alpha1 = 0.0; double alpha2 = 0.0; // We have strong constraints on the number of intermediate points // we can add. if( OGRGeometryFactory::GetCurveParmeters(x0, y0, x1, y1, x2, y2, R, cx, cy, alpha0, alpha1, alpha2) ) { // It is an arc circle. const double dfSegLength = fabs(alpha2 - alpha0) * R; if( dfSegLength > 0 ) { if( (dfLength <= dfDistance) && ((dfLength + dfSegLength) >= dfDistance) ) { const double dfRatio = (dfDistance - dfLength) / dfSegLength; const double alpha = alpha0 * (1 - dfRatio) + alpha2 * dfRatio; const double x = cx + R * cos(alpha); const double y = cy + R * sin(alpha); poPoint->setX( x ); poPoint->setY( y ); if( getCoordinateDimension() == 3 ) poPoint->setZ( padfZ[i] * (1 - dfRatio) + padfZ[i+2] * dfRatio ); return; } dfLength += dfSegLength; } } else { // It is a straight line. const double dfSegLength = dist(x0, y0, x2, y2); if( dfSegLength > 0 ) { if( (dfLength <= dfDistance) && ((dfLength + dfSegLength) >= dfDistance) ) { const double dfRatio = (dfDistance - dfLength) / dfSegLength; poPoint->setX( paoPoints[i].x * (1 - dfRatio) + paoPoints[i+2].x * dfRatio ); poPoint->setY( paoPoints[i].y * (1 - dfRatio) + paoPoints[i+2].y * dfRatio ); if( getCoordinateDimension() == 3 ) poPoint->setZ( padfZ[i] * (1 - dfRatio) + padfZ[i+2] * dfRatio ); return; } dfLength += dfSegLength; } } } EndPoint( poPoint ); }
EIntersection IntersectLineCone(const idVec3 rkLine[LSG_COUNT], idVec3 rkCone[ELC_COUNT], idVec3 Intersect[2], bool Stump) { EIntersection rc = INTERSECT_COUNT; int i, n, l, x; float t, angle; idPlane lightProject[4]; idPlane frustum[6]; int Start[6]; int End[6]; bool bStart, bEnd; bool bCalcIntersection; idStr txt; idStr format("Frustum[%u]"); idVec3 EndPoint(rkLine[LSG_ORIGIN]+rkLine[LSG_DIRECTION]); DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING(" rkLine[LSG_ORIGIN] = [%s]\r", rkLine[LSG_ORIGIN].ToString()); DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING(" rkLine[LSG_DIRECTION] = [%s]\r", rkLine[LSG_DIRECTION].ToString()); DM_LOG(LC_LIGHT, LT_DEBUG)LOGSTRING(" EndPoint = [%s]\r", EndPoint.ToString()); R_SetLightProject(lightProject, rkCone[ELC_ORIGIN], rkCone[ELA_TARGET], rkCone[ELA_RIGHT], rkCone[ELA_UP], rkCone[ELA_START], rkCone[ELA_END]); R_SetLightFrustum(lightProject, frustum); /* DM_LOGPLANE(LC_MATH, LT_DEBUG, "Light[0]", lightProject[0]); DM_LOGPLANE(LC_MATH, LT_DEBUG, "Light[1]", lightProject[1]); DM_LOGPLANE(LC_MATH, LT_DEBUG, "Light[2]", lightProject[2]); DM_LOGPLANE(LC_MATH, LT_DEBUG, "Light[3]", lightProject[3]); */ n = format.Length(); // Calculate the angle between the target and the lightvector. angle = rkCone[ELA_TARGET].Length() * rkLine[LSG_DIRECTION].Length(); DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Denominator: %f\r", angle); if ( angle >= idMath::FLT_EPSILON ) { angle = idMath::ACos((rkCone[ELA_TARGET] * rkLine[LSG_DIRECTION])/angle); // if(t > (idMath::PI/2)) // angle = idMath::PI - angle; DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Angle: %f\r", angle); } else { DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Impossible line!\r"); } bCalcIntersection = false; l = 0; for ( i = 0 ; i < 6 ; i++ ) { sprintf(txt, format, i); DM_LOGPLANE(LC_MATH, LT_DEBUG, txt, frustum[i]); Start[i] = frustum[i].Side(rkLine[LSG_ORIGIN], idMath::FLT_EPSILON); End[i] = frustum[i].Side(EndPoint, idMath::FLT_EPSILON); DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Frustum[%u]: Start %u End: %u\r", i, Start[i], End[i]); // If the points are all on the outside there will be no intersections if ( ( Start[i] == PLANESIDE_BACK ) || ( End[i] == PLANESIDE_BACK ) ) { bCalcIntersection = true; } } DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("CalcIntersection: %u\r", bCalcIntersection); if (bCalcIntersection == true) { DM_LOGVECTOR3(LC_MATH, LT_DEBUG, "TargetOrigin", rkLine[LSG_ORIGIN]); DM_LOGVECTOR3(LC_MATH, LT_DEBUG, "TargetDirection", rkLine[LSG_DIRECTION]); DM_LOGVECTOR3(LC_MATH, LT_DEBUG, "Endpoint", EndPoint); for(i = 0; i < 6; i++) { if (frustum[i].LineIntersection(rkLine[LSG_ORIGIN], rkLine[LSG_DIRECTION], &t) == true) { DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Frustum[%u] intersects\r", i); Intersect[l] = rkLine[LSG_ORIGIN] + t*rkLine[LSG_DIRECTION]; l++; if (l > 1) { break; } } } } if (l < 2) { rc = INTERSECT_OUTSIDE; } else { rc = INTERSECT_FULL; bStart = bEnd = true; for (i = 0; i < 6; i++) { x = frustum[i].Side(Intersect[0], idMath::FLT_EPSILON); DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Frustum[%u/0] intersection test returns %u\r", i, x); if (x != PLANESIDE_BACK) { bStart = false; } x = frustum[i].Side(Intersect[1], idMath::FLT_EPSILON); DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Frustum[%u/1] intersection test returns %u\r", i, x); if (x != PLANESIDE_BACK) { bEnd = false; } } if (bStart == false && bEnd == false) { rc = INTERSECT_OUTSIDE; } } DM_LOG(LC_MATH, LT_DEBUG)LOGSTRING("Intersection count = %u\r", l); DM_LOGVECTOR3(LC_MATH, LT_DEBUG, "akPoint[0]", Intersect[0]); DM_LOGVECTOR3(LC_MATH, LT_DEBUG, "akPoint[1]", Intersect[1]); return rc; }
void PathProcessorStrokeAirbrush::ProcessPath(Path *pPath, RenderRegion *pRender, PathShape ShapePath) { PORTNOTETRACE("other","PathProcessorStrokeAirbrush::ProcessPath - do nothing"); #ifndef EXCLUDE_FROM_XARALX ERROR3IF(pPath == NULL || pRender == NULL, "Illegal NULL Params"); // --- If the provided path is not stroked, then we'll just pass it straight through // We also don't touch it if we're doing EOR rendering, or click regions // BLOCK { StrokeColourAttribute *pStrokeColour = (StrokeColourAttribute *) pRender->GetCurrentAttribute(ATTR_STROKECOLOUR); if (pRender->DrawingMode != DM_COPYPEN || pRender->IsHitDetect() || !pPath->IsStroked || pStrokeColour == NULL || pStrokeColour->Colour.IsTransparent()) { pRender->DrawPath(pPath, this, ShapePath); return; } } // --- If the quality is set low, strokes are just rendered as centrelines // BLOCK { QualityAttribute *pQuality = (QualityAttribute *) pRender->GetCurrentAttribute(ATTR_QUALITY); if (pQuality != NULL && pQuality->QualityValue.GetLineQuality() != Quality::FullLine) { pRender->DrawPath(pPath, this, ShapePath); return; } } // --- If the attribute which created us is not the current StrokeType attribute, then // we have been overridden by a different stroke type, so we do nothing. // BLOCK { StrokeTypeAttrValue *pTypeAttr = (StrokeTypeAttrValue *) pRender->GetCurrentAttribute(ATTR_STROKETYPE); if (pTypeAttr != NULL && pTypeAttr != GetParentAttr()) { pRender->DrawPath(pPath, this, ShapePath); return; } } // --- Get the current line width from the render region // In case of failure, we initialise with suitable defaults INT32 LineWidth = 5000; // BLOCK { LineWidthAttribute *pWidthAttr = (LineWidthAttribute *) pRender->GetCurrentAttribute(ATTR_LINEWIDTH); if (pWidthAttr != NULL) LineWidth = pWidthAttr->LineWidth; } // Obtain an optimal number of steps for the line // When printing, we do heaps of steps to get top quality out the other end View *pView = pRender->GetRenderView(); ERROR3IF(pView == NULL, "No render view?!"); INT32 NumSteps = MaxAirbrushSteps; if (!pRender->IsPrinting()) GetNumSteps(pView, LineWidth); // --- Now, create a transparency mask bitmap for the airbrush Spread *pSpread = pRender->GetRenderSpread(); // ERROR3IF(pSpread == NULL, "No render spread!?"); // This can happen, rendering into a gallery // Get the render region's clip rectangle in Spread Coords. We don't need to // render anything bigger than this size, so it is the upper limit on our bitmap area. DocRect ClipRegion = pRender->GetClipRect(); // Intersect this with the path bounding rectangle to get the actual region we need to redraw // The smaller this is, the faster we go and the less memory we use. //DocRect PathRect = pPath->GetBoundingRect(); DocRect PathRect = pPath->GetBlobRect(); PathRect.Inflate(LineWidth); BOOL Intersects = ClipRegion.IsIntersectedWith(PathRect); if(!Intersects) { // Don't bother drawing anything - it's clipped out return; } ClipRegion = ClipRegion.Intersection(PathRect); // Round the ClipRegion edges up so they all lie exactly on screen pixel boundaries. // If we don't do this, then there can be a sub-pixel rounding error between the ClipRegion // and the actual bitmap size, so that the bitmap is scaled slightly when we plot it. // By making sure it's pixelised, we guarantee that the bitmap & clipregion are exactly equal sizes. // (It doesn't matter if the bitmap is a bit bigger than necessary) ClipRegion.Inflate(pRender->GetScaledPixelWidth()); ClipRegion.lo.Pixelise(pView); ClipRegion.hi.Pixelise(pView); // Get the current view's rendering matrix and view scale Matrix ConvMatrix = pRender->GetMatrix();//pView->ConstructRenderingMatrix(pSpread); FIXED16 ViewScale = pView->GetViewScale(); // Generate a 256-colour greyscale palette LOGPALETTE *pPalette = MakeGreyScalePalette(); if(pPalette == NULL) { pRender->DrawPath(pPath, this, ShapePath); return; } // Work out the DPI to use. Rather than just asking for PixelWidth or DPI from the // render region, we have to do a load of non-object-oriented stuff instead... double dpi = 96.0; if (pRender->IsPrinting()) { // we are printing, so ask the print options PrintControl *pPrintControl = pView->GetPrintControl(); if (pPrintControl != NULL) dpi = (double) pPrintControl->GetDotsPerInch(); } else if (IS_A(pRender, CamelotEPSRenderRegion)) { // Use DPI as set in EPS export options dialog. dpi = (double) EPSFilter::XSEPSExportDPI; } else { ERROR3IF(pRender->GetPixelWidth() <= 0, "Stupid (<1 millipoint) Pixel Width!"); if (pRender->GetPixelWidth() > 0) dpi = (double) (72000.0 / (double)pRender->GetPixelWidth()); } GRenderBitmap *pMaskRegion = new GRenderBitmap(ClipRegion, ConvMatrix, ViewScale, 8, dpi, pRender->IsPrinting(), XARADITHER_ORDERED_GREY, pPalette, FALSE); if (pMaskRegion == NULL) { pRender->DrawPath(pPath, this, ShapePath); return; } BOOL PathIsFilled = FALSE; // Will be set TRUE if this path should be filled at the bottom of the function //BLOCK { // Change the GDraw context in this render region so as to preserve the state // of the main render region. This is because GRenderRegions currently use // a single static GDrawContext! This also sets it up with a nice greyscale palette // so that we get the output we desire. pMaskRegion->UseGreyscaleContextDangerous(); // Attach our DC to the view and render region... if (pMaskRegion->AttachDevice(pView, NULL, pSpread)) { pMaskRegion->StartRender(); // We must save & restore the attribute state around all our rendering because // attributes otherwise stay on the renderstack until we delete the RndRgn, and as our // ones are on the program stack, they will have ceased to exist before then, which // makes for a wicked explosion. pMaskRegion->SaveContext(); ///////////////////////////////////////////////////////////////////////////////////// // --- Main Airbrush rendering loop // Make sure we've got an intensity function to use. This will create a new one if necessary ValueFunction *pvValueFunction = GetIntensityFunction(); if (pvValueFunction == NULL) { ERROR3("Failed to set an intensity function on an airbrush stroke"); pRender->DrawPath(pPath, this, ShapePath); return; } if(!RenderAirBrush(pPath, pMaskRegion, LineWidth, NumSteps, pvValueFunction, pRender, ShapePath)) { // Airbrush failed - just render the path without the airbrush effect pRender->DrawPath(pPath, this, ShapePath); return; } pMaskRegion->RestoreContext(); // --- ClipRect test code ///////////////////////////////////////////////////////////////////////////////////// // --- We have drawn the airbrushed stroke - now, if the path is filled, we // will render the filled area, so that in semi-transparent cases, the // stroke will not "show through" from behind the filled area. if (pPath->IsFilled) { ColourFillAttribute *pCFAttr = (ColourFillAttribute *) pRender->GetCurrentAttribute(ATTR_FILLGEOMETRY); if (pCFAttr != NULL && (!pCFAttr->Colour.IsTransparent() || pCFAttr->IsABitmapFill())) { PathIsFilled = TRUE; pMaskRegion->SaveContext(); ColourFillAttribute *pFillAttr = NULL; FillMappingAttribute *pMapAttr = NULL; // Obtain the object's transparent fill geometry TranspFillAttribute *pTransAttr = (TranspFillAttribute *) pRender->GetCurrentAttribute(ATTR_TRANSPFILLGEOMETRY); if (pTransAttr != NULL) { // Get a non-transparent version of the fill geometry pFillAttr = pTransAttr->MakeSimilarNonTranspFillGeometry(1.0); // Convert a fill mapping TranspFillMappingAttribute *pTransMapAttr = (TranspFillMappingAttribute *) pRender->GetCurrentAttribute(ATTR_TRANSPFILLMAPPING); if(pTransMapAttr != NULL) pMapAttr = pTransMapAttr->MakeSimilarNonTranspFillMapping(); } // Setup region and draw path into it if (pFillAttr != NULL) { pMaskRegion->SetFillGeometry(pFillAttr, TRUE); if(pMapAttr != NULL) pMaskRegion->SetFillMapping(pMapAttr, TRUE); } else pMaskRegion->SetFillColour(DocColour(0, 0, 0)); pMaskRegion->SetLineColour(DocColour(COLOUR_TRANS)); pMaskRegion->DrawPath(pPath, NULL, ShapePath); pMaskRegion->RestoreContext(); } } pMaskRegion->StopRender(); } pMaskRegion->StopUsingGreyscaleContextDangerous(); } // Extract the transparency mask bitmap from the render region OILBitmap *pOilBmp = pMaskRegion->ExtractBitmap(); // We no longer need the RenderRegion, so scrap it. delete pMaskRegion; pMaskRegion = NULL; pPalette = NULL; // Now, render a rectangle to the output render region, using the transparency mask if (pOilBmp == NULL) return; KernelBitmap *pMask = new KernelBitmap(pOilBmp, TRUE); if (pMask != NULL) { // Make sure the bitmap knows it's already a greyscale, else it will spend a lot of // time "converting" itself to a greyscale, and what's more, corrupting the grey levels // so that 255 (invisible) becomes 254 (slightly visible). Arrrrrgh! pMask->SetAsGreyscale(); // Create a transparency attribute from our mask bitmap BitmapTranspFillAttribute Trans; // We don't call pTrans->AttachBitmap because it seems to be stupid, and causes ructions // when we try to attach a temporary bitmap. We thus do the same thing, but avoiding // its attempts to automatically screw us about. Trans.BitmapRef.Detach(); Trans.BitmapRef.SetBitmap(pMask); Trans.SetStartPoint(&ClipRegion.lo); DocCoord EndPoint(ClipRegion.hi.x, ClipRegion.lo.y); Trans.SetEndPoint(&EndPoint); DocCoord EndPoint2(ClipRegion.lo.x, ClipRegion.hi.y); Trans.SetEndPoint2(&EndPoint2); UINT32 TValue = 0; Trans.SetStartTransp(&TValue); TValue = 255; Trans.SetEndTransp(&TValue); // Use the same transparency type as is set on the object being rendered (if any) { TranspFillAttribute *pTransAttr = (TranspFillAttribute *) pRender->GetCurrentAttribute(ATTR_TRANSPFILLGEOMETRY); if (pTransAttr != NULL) Trans.SetTranspType(pTransAttr->GetTranspType()); else Trans.SetTranspType(TT_Mix); // By default, we'll use Mix transparency } // --- OK, we finally got here! Render the stroke, using the transparency mask we just made pRender->SaveContext(); Trans.Render(pRender); // Render the path. If it is filled, then we render the entire thing (fill & stroke) using // the current fill geometry (to get a shadow/feather effect) if (PathIsFilled) { // Render the entire thing (fill & stroke) in one go. We render a rectangle over the cliprect // so that we do everything in one go (we can't render the fill &7 stroke separately, or // the transparency will overlap & it'll look wrong) pRender->SetLineColour(DocColour(COLOUR_TRANS)); // Don't render a line Path Rect; Rect.Initialise(); Rect.AddMoveTo(ClipRegion.lo); Rect.AddLineTo(DocCoord(ClipRegion.hix, ClipRegion.loy)); Rect.AddLineTo(ClipRegion.hi); Rect.AddLineTo(DocCoord(ClipRegion.lox, ClipRegion.hiy)); Rect.AddLineTo(ClipRegion.lo); Rect.IsFilled = TRUE; Rect.IsStroked = FALSE; pRender->DrawPath(&Rect, this, ShapePath); } else { // Otherwise, create a filled-outline path for the entire stroke, and render it // !!!!****ToDo - for now, strokes always render flat-filled with the stroke colour StrokeColourAttribute *pStrokeColour = (StrokeColourAttribute *) pRender->GetCurrentAttribute(ATTR_STROKECOLOUR); if (pStrokeColour != NULL) pRender->SetFillColour(pStrokeColour->Colour); // Fill the holes pRender->SetWindingRule(NonZeroWinding); Path *pOutput = CreateVarWidthStroke(pPath, pRender, LineWidth); if (pOutput != NULL) { pRender->DrawPath(pOutput, NULL, ShapePath); delete pOutput; pOutput = NULL; } } pRender->RestoreContext(); // Delete the kernel bitmap. This auto-deletes the OIL bitmap for us delete pMask; } #endif }