Example #1
0
/**
	The location is relative both to (0,0,0) and, from there, to the point along the text string
	for this character.  The transformation matrix is both a translation (movement) and a
	rotation function that is maintained by the HText class based on where the operator has
	placed the text.  i.e. the location is in 'internal' coordinates and those are then
	transformed (moved and/or rotated) by the rotation matrix to determine the final
	coordinates.  This is handled differently to the glCommands() method because the OpenGL
	libraries will have had the transformation matrix pushed onto the stack so that all
	OpenGL coordinates will be implicitly transformed.
 */
HeeksObj *VectorFont::Glyph::Sketch( const gp_Pnt & location, const gp_Trsf & transformation_matrix, const float width, COrientationModifier *pOrientationModifier ) const
{
	HeeksObj *sketch = heekscad_interface.NewSketch();

	for (GraphicsList_t::const_iterator l_itGraphic = m_graphics_list.begin(); l_itGraphic != m_graphics_list.end(); l_itGraphic++)
	{
		sketch->Add((*l_itGraphic)->Sketch( location, transformation_matrix, width, pOrientationModifier ), NULL);
	} // End for

	return(sketch);
} // End Sketch() method
Example #2
0
static void SimplifySketch(const double deviation, bool make_bspline )
{

    wxGetApp().CreateUndoPoint();

    double original_tolerance = wxGetApp().m_geom_tol;
    wxGetApp().m_geom_tol = sketch_tool_options.m_cleanup_tolerance;

    std::list<HeeksObj *> selected_sketches;
    std::copy( wxGetApp().m_marked_list->list().begin(), wxGetApp().m_marked_list->list().end(),
                std::inserter( selected_sketches, selected_sketches.begin() ));

	std::list<HeeksObj*>::const_iterator It;
	for(It = selected_sketches.begin(); It != selected_sketches.end(); It++){
		HeeksObj* object = *It;
		std::list<HeeksObj *> new_objects;

		if (object->GetType() == SketchType)
		{
			std::list<TopoDS_Shape> wires;
			try {
				heekscad_interface.ConvertSketchToFaceOrWire(object, wires, false);
			} // End try
			catch(...)
			{
				continue;
			}
			for (std::list<TopoDS_Shape>::iterator itWire = wires.begin(); itWire != wires.end(); itWire++)
			{
				std::list<SimplifySketchTool::SortPoint> points = SimplifySketchTool::GetPoints( TopoDS::Wire(*itWire), deviation );

				if (sketch_tool_options.m_sort_points)
				{
					// The sort points option is turned on.  The idea of this is to detect shapes that include
					// sections that 'double back' on themselves.  The first example being a shape made up of
					// a box as well as a single line that layed along one edge of the box.  In this case the extra
					// line was superfluous.  If we sort the points so that each point is closest to the previous
					// point then, hopefully, we will reorder these shapes that double back on themselves.  If this
					// doesn't work then the user can always turn the 'sort points' option off and try again.

					std::vector<SimplifySketchTool::SortPoint> sorted_points;
					std::copy( points.begin(), points.end(), std::inserter( sorted_points, sorted_points.begin() ));

					for (std::vector<SimplifySketchTool::SortPoint>::iterator l_itPoint = sorted_points.begin(); l_itPoint != sorted_points.end(); l_itPoint++)
					{
						// We've already begun.  Just sort based on the previous point's location.
						std::vector<SimplifySketchTool::SortPoint>::iterator l_itNextPoint = l_itPoint;
						l_itNextPoint++;

						if (l_itNextPoint != sorted_points.end())
						{
							SimplifySketchTool::sort_points_by_distance compare( *l_itPoint );
							std::sort( l_itNextPoint, sorted_points.end(), compare );
						} // End if - then
					} // End for

					points.clear();
					std::copy( sorted_points.begin(), sorted_points.end(), std::inserter( points, points.begin() ));

					// This sorting process will have resulted in the start and end points being located next to each other
					// and hence removed.  If the original wire was periodic (closed shape) then make sure the last point
					// is the same as the first point.

					TopoDS_Wire wire(TopoDS::Wire(*itWire));
					if (wire.Closed())
					{
						if (*(points.begin()) != *(points.rbegin()))
						{
							points.push_back(*points.begin());	// Close the shape manually.
						}
					}
				}

				// Whether we sorted or not, we may want to close the shape.
				if (sketch_tool_options.m_force_closed_shape)
				{
					if (*(points.begin()) != *(points.rbegin()))
					{
						points.push_back(*points.begin());	// Close the shape manually.
					}
				}

				// Now keep removing points from this list as long as the midpoints are within deviation of
				// the line between the two neighbour points.
				bool points_removed = false;
				do {
					points_removed = false;

					for (std::list<SimplifySketchTool::SortPoint>::iterator itPoint = points.begin(); itPoint != points.end(); itPoint++ )
					{
						std::list<SimplifySketchTool::SortPoint>::iterator itP1 = itPoint;
						std::list<SimplifySketchTool::SortPoint>::iterator itP2 = itPoint;
						std::list<SimplifySketchTool::SortPoint>::iterator itP3 = itPoint;

						itP2++;
						if (itP2 != points.end())
						{
							itP3 = itP2;
							itP3++;

							if (itP3 != points.end())
							{
								// First see if p1 and p2 are too close to each other.
								if (itP1->Distance(*itP2) < deviation)
								{
									// Discard p2.
									points.erase(itP2);
									points_removed = true;
									continue;
								}

								if (itP2->Distance(*itP3) < deviation)
								{
									// Discard p2
									points.erase(itP2);
									points_removed = true;
									continue;
								}

                                if (itP1->Distance(*itP3) > deviation)
                                {
                                    // Now draw a line between p1 and p3.  Measure the distance between p2 and the nearest point
                                    // along that line.  If this distance is less than the max deviation then discard p2.
                                    gp_Lin line(*itP1, gp_Dir(itP3->X() - itP1->X(), itP3->Y() - itP1->Y(), itP3->Z() - itP1->Z()));
                                    if (line.SquareDistance(*itP2) < deviation)
                                    {
                                        // Discard p2
                                        points.erase(itP2);
                                        points_removed = true;
                                        continue;
                                    }
                                }
							}
						}
					} // End for
				} while (points_removed == true);

				if (points.size() >= 2)
				{
					


				    if (make_bspline)
				    {
				        try {
                            TColgp_Array1OfPnt Points(0, points.size()-1);
                            Standard_Integer i=0;
                            for (std::list<SimplifySketchTool::SortPoint>::iterator itPoint = points.begin(); itPoint != points.end(); itPoint++, i++)
                            {
                                Points.SetValue(i, *itPoint);
                            }

                            // GeomAPI_PointsToBSpline bspline(Points);

                            GeomAPI_PointsToBSpline bspline(Points,
                                                            sketch_tool_options.m_degree_min,
                                                            sketch_tool_options.m_degree_max,
                                                            GeomAbs_Shape(sketch_tool_options.m_continuity),
                                                            sketch_tool_options.m_cleanup_tolerance);

                            // Standard_EXPORT GeomAPI_PointsToBSpline(const TColgp_Array1OfPnt& Points,const Standard_Integer DegMin = 3,const Standard_Integer DegMax = 8,const GeomAbs_Shape Continuity = GeomAbs_C2,const Standard_Real Tol3D = 1.0e-3);

                            HSpline *hspline = new HSpline(bspline.Curve(), &(wxGetApp().current_color));
                            heekscad_interface.Add( hspline, NULL );
				        }
				        catch (Standard_Failure) {
                            Handle_Standard_Failure e = Standard_Failure::Caught();
                            wxMessageBox(_("Failed to create BSpline curve"));
                        }
				    } // End if - then
				    else
				    {
				        // We're making straight lines

                        HeeksObj *sketch = heekscad_interface.NewSketch();
                        for (std::list<SimplifySketchTool::SortPoint>::iterator itPoint = points.begin(); itPoint != points.end(); itPoint++)
                        {
                            std::list<SimplifySketchTool::SortPoint>::iterator itNext = itPoint;
                            itNext++;
                            if (itNext == points.end()) continue;

                            double start[3], end[3];
                            itPoint->ToDoubleArray(start);
                            itNext->ToDoubleArray(end);

                            sketch->Add(heekscad_interface.NewLine(start, end), NULL);
                        } // End for

                        // heekscad_interface.Add(sketch, NULL);
                        new_objects.push_back(sketch);
				    } // End if - else
				} // End if - then
			} // End for

            if (new_objects.size() > 0)
            {
#ifdef MULTIPLE_OWNERS
                std::list<HeeksObj *> parents = object->Owners();
                for (std::list<HeeksObj *>::iterator itOwner = parents.begin(); itOwner != parents.end(); itOwner++)
                {
#else
				if(object->m_owner)
				{
#endif
                    if ((object->CanEditString()) && (object->GetShortString()))
                    {
                        // (*itOwner)->Remove(object);

                        // Mark the old sketches with a name that can be easily recognised so that we can delete the
                        // old objects if we're satisfied with the replacements.
                        wxString title;
                        title << _("Replaced ") << object->GetShortString();
                        object->OnEditString(title);
                    } // End if - then

                    for (std::list<HeeksObj *>::iterator itNewChild = new_objects.begin(); itNewChild != new_objects.end(); itNewChild++)
                    {
#ifdef MULTIPLE_OWNERS
                        (*itOwner)->Add( *itNewChild, NULL );
#else
                        object->m_owner->Add( *itNewChild, NULL );
#endif
                    } // End for
                } // End for
            } // End if - then
		} // End if - then
	} // End for

    wxGetApp().m_geom_tol = original_tolerance;
    wxGetApp().Changed();
}

void SimplifySketchTool::Run()
{
    SimplifySketch(m_deviation, false);
} // End Run() method