Base: refactoring of Builder3D/InventorBuilder
This commit is contained in:
@@ -105,264 +105,6 @@ const char* PolygonOffset::styleAsString() const
|
||||
return "FILLED";
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
*/
|
||||
Builder3D::Builder3D()
|
||||
: bStartEndOpen(false)
|
||||
{
|
||||
result << "#Inventor V2.1 ascii \n\n";
|
||||
result << "Separator { ";
|
||||
}
|
||||
|
||||
/**
|
||||
* A destructor.
|
||||
* A more elaborate description of the destructor.
|
||||
*/
|
||||
Builder3D::~Builder3D() = default;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// points handling
|
||||
|
||||
/**
|
||||
* Starts the definition of point set with the given point size and color.
|
||||
* If possible don't make too many startPoints() and endPoints() calls.
|
||||
* Try to put all points in one set.
|
||||
* @see endPoints()
|
||||
* @param pointSize the point size in pixel that are displayed.
|
||||
* @param ColorRGB point color.
|
||||
*/
|
||||
void Builder3D::startPoints(short pointSize, const ColorRGB& color)
|
||||
{
|
||||
bStartEndOpen = true;
|
||||
result << "Separator { ";
|
||||
result << "Material { ";
|
||||
result << "diffuseColor " << color.red() << " "<< color.green() << " " << color.blue();
|
||||
result << "} ";
|
||||
result << "MaterialBinding { value PER_PART } ";
|
||||
result << "DrawStyle { pointSize " << pointSize << "} ";
|
||||
result << "Coordinate3 { ";
|
||||
result << "point [ ";
|
||||
}
|
||||
|
||||
/// add a point to a point set
|
||||
void Builder3D::addPoint(const Vector3f &point)
|
||||
{
|
||||
result << point.x << " " << point.y << " " << point.z << ",";
|
||||
}
|
||||
/**
|
||||
* Ends the point set operations and write the resulting inventor string.
|
||||
* @see startPoints()
|
||||
*/
|
||||
void Builder3D::endPoints()
|
||||
{
|
||||
result << "] ";
|
||||
result << "} ";
|
||||
result << "PointSet { } ";
|
||||
result << "} ";
|
||||
bStartEndOpen = false;
|
||||
}
|
||||
|
||||
void Builder3D::addSinglePoint(const Base::Vector3f &point, DrawStyle drawStyle, const ColorRGB& color)
|
||||
{
|
||||
// addSinglePoint() not between startXXX() and endXXX() allowed
|
||||
assert(!bStartEndOpen);
|
||||
|
||||
result << "Separator { ";
|
||||
result << "Material { ";
|
||||
result << "diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue();
|
||||
result << "} ";
|
||||
result << "MaterialBinding { value PER_PART } ";
|
||||
result << "DrawStyle { pointSize " << drawStyle.pointSize << "} ";
|
||||
result << "Coordinate3 { ";
|
||||
result << "point [ ";
|
||||
result << point.x << " " << point.y << " " << point.z << ",";
|
||||
result << "] ";
|
||||
result << "} ";
|
||||
result << "PointSet { } ";
|
||||
result << "} ";
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// text handling
|
||||
|
||||
|
||||
/**
|
||||
* Add a Text with a given position to the 3D set. The origin is the
|
||||
* lower leftmost corner.
|
||||
* @param point origin of the text
|
||||
* @param text the text to display.
|
||||
* @param color text color.
|
||||
*/
|
||||
void Builder3D::addText(const Base::Vector3f& point, const char * text, const Base::ColorRGB& color)
|
||||
{
|
||||
// addSinglePoint() not between startXXX() and endXXX() allowed
|
||||
assert(!bStartEndOpen);
|
||||
|
||||
result << "Separator { "
|
||||
<< "Material { diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue() << "} "
|
||||
<< "Transform { translation " << point.x << " "<< point.y << " "<< point.z << "} "
|
||||
<< "Text2 { string \" " << text << "\" " << "} "
|
||||
<< "} ";
|
||||
}
|
||||
|
||||
void Builder3D::clear ()
|
||||
{
|
||||
// under gcc stringstream::str() returns a copy not a reference
|
||||
#if defined(_MSC_VER)
|
||||
result.str().clear();
|
||||
#endif
|
||||
result.clear();
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// line/arrow handling
|
||||
|
||||
void Builder3D::addSingleLine(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& color)
|
||||
{
|
||||
std::string pattern = drawStyle.patternAsString();
|
||||
|
||||
result << "Separator { "
|
||||
<< "Material { diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue() << "} "
|
||||
<< "DrawStyle { lineWidth " << drawStyle.lineWidth << " linePattern " << pattern << " } "
|
||||
<< "Coordinate3 { "
|
||||
<< "point [ "
|
||||
<< line.p1.x << " " << line.p1.y << " " << line.p1.z << ","
|
||||
<< line.p2.x << " " << line.p2.y << " " << line.p2.z
|
||||
<< "] "
|
||||
<< "} "
|
||||
<< "LineSet { } "
|
||||
<< "} ";
|
||||
}
|
||||
|
||||
void Builder3D::addSingleArrow(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& color)
|
||||
{
|
||||
float length = line.Length();
|
||||
float coneLength = length / 10.0F;
|
||||
float coneRadius = coneLength / 2.0F;
|
||||
float sf1 = length - coneLength;
|
||||
float sf2 = length - coneLength/2.0F;
|
||||
|
||||
Vector3f dir = line.GetDirection();
|
||||
dir.Normalize();
|
||||
dir.Scale(sf1, sf1, sf1);
|
||||
Vector3f pt2s = line.p1 + dir;
|
||||
dir.Normalize();
|
||||
dir.Scale(sf2, sf2, sf2);
|
||||
Vector3f cpt = line.p1 + dir;
|
||||
|
||||
Vector3f rot = Vector3f(0.0f, 1.0f, 0.0f) % dir;
|
||||
rot.Normalize();
|
||||
float a = Vector3f(0.0f, 1.0f, 0.0f).GetAngle(dir);
|
||||
|
||||
result << "Separator { "
|
||||
<< "Material { diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue() << "} "
|
||||
<< "DrawStyle { lineWidth " << drawStyle.lineWidth << "} "
|
||||
<< "Coordinate3 { "
|
||||
<< "point [ "
|
||||
<< line.p1.x << " " << line.p1.y << " " << line.p1.z << ","
|
||||
<< pt2s.x << " " << pt2s.y << " " << pt2s.z
|
||||
<< "] "
|
||||
<< "} "
|
||||
<< "LineSet { } "
|
||||
<< "Transform { "
|
||||
<< "translation " << cpt.x << " " << cpt.y << " " << cpt.z << " "
|
||||
<< "rotation " << rot.x << " " << rot.y << " " << rot.z << " " << a
|
||||
<< "} "
|
||||
<< "Cone { bottomRadius " << coneRadius << " height " << coneLength << "} "
|
||||
<< "} ";
|
||||
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// triangle handling
|
||||
|
||||
void Builder3D::addSingleTriangle(const Triangle& triangle, DrawStyle drawStyle, const ColorRGB& color)
|
||||
{
|
||||
std::string fs = "";
|
||||
if (drawStyle.style == DrawStyle::Style::Filled) {
|
||||
fs = "IndexedFaceSet { coordIndex[ 0, 1, 2, -1 ] } ";
|
||||
}
|
||||
|
||||
result << "Separator { "
|
||||
<< "Material { diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue() << "} "
|
||||
<< "DrawStyle { lineWidth " << drawStyle.lineWidth << "} "
|
||||
<< "Coordinate3 { "
|
||||
<< "point [ "
|
||||
<< triangle.getPoint1().x << " " << triangle.getPoint1().y << " " << triangle.getPoint1().z << ","
|
||||
<< triangle.getPoint2().x << " " << triangle.getPoint2().y << " " << triangle.getPoint2().z << ","
|
||||
<< triangle.getPoint3().x << " " << triangle.getPoint3().y << " " << triangle.getPoint3().z << ","
|
||||
<< "] "
|
||||
<< "} "
|
||||
<< "LineSet { } "
|
||||
<< fs
|
||||
<< "} ";
|
||||
}
|
||||
|
||||
void Builder3D::addTransformation(const Base::Matrix4D& transform)
|
||||
{
|
||||
Base::Placement placement;
|
||||
placement.fromMatrix(transform);
|
||||
addTransformation(placement);
|
||||
}
|
||||
|
||||
void Builder3D::addTransformation(const Base::Placement& transform)
|
||||
{
|
||||
Base::Vector3d translation = transform.getPosition();
|
||||
Base::Vector3d rotationaxis;
|
||||
double angle{};
|
||||
transform.getRotation().getValue(rotationaxis, angle);
|
||||
result << "Transform {";
|
||||
result << " translation " << translation.x << " " << translation.y << " " << translation.z;
|
||||
result << " rotation " << rotationaxis.x << " " << rotationaxis.y << " " << rotationaxis.z << " " << angle;
|
||||
result << "}";
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// output handling
|
||||
|
||||
/**
|
||||
* Save the resulting inventor 3D representation to the Console().Log() facility.
|
||||
* In DEBUG mode the Gui (if running) will trigger on that and show the representation in
|
||||
* the active Viewer/Document. It shows only one representation on time. If you need to
|
||||
* show more then one representation use saveToFile() instead.
|
||||
* @see saveToFile()
|
||||
*/
|
||||
void Builder3D::saveToLog()
|
||||
{
|
||||
result << "} ";
|
||||
// Note: The string can become very long, so that ConsoleSingelton::Log() will internally
|
||||
// truncate the string which causes Inventor to fail to interpret the truncated string.
|
||||
// So, we send the string directly to the observer that handles the Inventor stuff.
|
||||
//Console().Log("Vdbg: %s \n",result.str().c_str());
|
||||
ILogger* obs = Base::Console().Get("StatusBar");
|
||||
if (obs){
|
||||
obs->SendLog(result.str().c_str(), Base::LogStyle::Log);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the resulting inventor 3D representation to a file. Ending should be *.iv.
|
||||
* That enables you to show the result in a Inventor Viewer or in FreeCAD by:
|
||||
* /code
|
||||
* Gui.document().addAnnotation("Debug","MyFile.iv")
|
||||
* /endcode
|
||||
* @see saveToFile()
|
||||
*/
|
||||
void Builder3D::saveToFile(const char* FileName)
|
||||
{
|
||||
result << "} ";
|
||||
Base::FileInfo fi(FileName);
|
||||
Base::ofstream file(fi);
|
||||
if (!file)
|
||||
throw FileException("Builder3D::saveToFile(): Can not open file...");
|
||||
|
||||
file << "#Inventor V2.1 ascii \n";
|
||||
file << result.str();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
InventorBuilder::InventorBuilder(std::ostream& output)
|
||||
@@ -539,6 +281,23 @@ void InventorBuilder::addPointSet()
|
||||
result << Base::blanks(indent) << "PointSet { } \n";
|
||||
}
|
||||
|
||||
void InventorBuilder::addSinglePoint(const Base::Vector3f &point, DrawStyle drawStyle, const ColorRGB& color)
|
||||
{
|
||||
result << Base::blanks(indent) << "Separator { ";
|
||||
result << Base::blanks(indent) << " Material { ";
|
||||
result << Base::blanks(indent) << " diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue();
|
||||
result << Base::blanks(indent) << " }";
|
||||
result << Base::blanks(indent) << " MaterialBinding { value PER_PART } ";
|
||||
result << Base::blanks(indent) << " DrawStyle { pointSize " << drawStyle.pointSize << "} ";
|
||||
result << Base::blanks(indent) << " Coordinate3 { ";
|
||||
result << Base::blanks(indent) << " point [ ";
|
||||
result << point.x << " " << point.y << " " << point.z << ",";
|
||||
result << Base::blanks(indent) << " ] ";
|
||||
result << Base::blanks(indent) << " }";
|
||||
result << Base::blanks(indent) << " PointSet { } ";
|
||||
result << Base::blanks(indent) <<"}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a SoLineSet node after creating a SoCordinate3 node with
|
||||
* beginPoints() and endPoints().
|
||||
@@ -923,6 +682,66 @@ void InventorBuilder::addTransformation(const Base::Placement& transform)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
*/
|
||||
Builder3D::Builder3D()
|
||||
: InventorBuilder(result)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* A destructor.
|
||||
* A more elaborate description of the destructor.
|
||||
*/
|
||||
Builder3D::~Builder3D() = default;
|
||||
|
||||
void Builder3D::clear ()
|
||||
{
|
||||
// under gcc stringstream::str() returns a copy not a reference
|
||||
#if defined(_MSC_VER)
|
||||
result.str().clear();
|
||||
#endif
|
||||
result.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the resulting inventor 3D representation to the Console().Log() facility.
|
||||
* In DEBUG mode the Gui (if running) will trigger on that and show the representation in
|
||||
* the active Viewer/Document. It shows only one representation on time. If you need to
|
||||
* show more then one representation use saveToFile() instead.
|
||||
* @see saveToFile()
|
||||
*/
|
||||
void Builder3D::saveToLog()
|
||||
{
|
||||
ILogger* obs = Base::Console().Get("StatusBar");
|
||||
if (obs){
|
||||
obs->SendLog(result.str().c_str(), Base::LogStyle::Log);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the resulting inventor 3D representation to a file. Ending should be *.iv.
|
||||
* That enables you to show the result in a Inventor Viewer or in FreeCAD by:
|
||||
* /code
|
||||
* Gui.document().addAnnotation("Debug","MyFile.iv")
|
||||
* /endcode
|
||||
* @see saveToFile()
|
||||
*/
|
||||
void Builder3D::saveToFile(const char* FileName)
|
||||
{
|
||||
Base::FileInfo fi(FileName);
|
||||
Base::ofstream file(fi);
|
||||
if (!file) {
|
||||
throw FileException("Cannot open file");
|
||||
}
|
||||
|
||||
file << result.str();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> InventorLoader::readData(const char* fieldName) const
|
||||
{
|
||||
|
||||
@@ -128,94 +128,6 @@ private:
|
||||
Base::Vector3f pt3;
|
||||
};
|
||||
|
||||
/** A Builder class for 3D representations on App level
|
||||
* On the application level nothing is known of the visual representation of data.
|
||||
* Nevertheless it's often needed to see some 3D information, e.g. points, directions,
|
||||
* when you program or debug an algorithm. Builder3D was made for this specific purpose.
|
||||
* This class allows you to easily build up a 3D representation of some mathematical and
|
||||
* algorithm internals. You can save this representation to a file and view it in an
|
||||
* Inventor viewer, or send it to the log. In the case of using the log and a debug
|
||||
* FreeCAD the representation will be loaded into the active viewer.
|
||||
* \par
|
||||
* The workflow goes as follows: Create the a Builder3D object and call the methods
|
||||
* to insert the graphical elements. After that call either saveToLog() or saveToFile().
|
||||
* \par
|
||||
* Usage:
|
||||
* \code
|
||||
Base::Builder3D log3D;
|
||||
for ( unsigned long i=0; i<pMesh->CountPoints(); i++ )
|
||||
{
|
||||
log3D.addSinglePoint(pMesh->GetPoint(i));
|
||||
log3D.addText(pMesh->GetPoint(i),"Point");
|
||||
...
|
||||
}
|
||||
log3D.saveToLog();
|
||||
* \endcode
|
||||
* \see Base::ConsoleSingleton
|
||||
*/
|
||||
class BaseExport Builder3D
|
||||
{
|
||||
public:
|
||||
Builder3D();
|
||||
virtual ~Builder3D();
|
||||
|
||||
/** @name point set handling */
|
||||
//@{
|
||||
/// starts a point set
|
||||
void startPoints(short pointSize=2, const ColorRGB& color = ColorRGB{1.0F, 0.0F, 0.0F});
|
||||
/// add a point to a point set
|
||||
void addPoint(const Vector3f& point);
|
||||
/// ends the points set operation
|
||||
void endPoints();
|
||||
/// add a single point (without startPoints() & endPoints() )
|
||||
void addSinglePoint(const Base::Vector3f& point, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
//@}
|
||||
|
||||
/** @name line/direction handling */
|
||||
//@{
|
||||
/// add a line
|
||||
void addSingleLine(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
/// add an arrow.
|
||||
void addSingleArrow(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
//@}
|
||||
|
||||
/** @name triangle handling */
|
||||
//@{
|
||||
/// add a triangle
|
||||
void addSingleTriangle(const Triangle& triangle, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
//@}
|
||||
|
||||
/** @name Transformation */
|
||||
//@{
|
||||
/// adds a transformation
|
||||
void addTransformation(const Base::Matrix4D&);
|
||||
void addTransformation(const Base::Placement&);
|
||||
//@}
|
||||
|
||||
/** @name text handling */
|
||||
//@{
|
||||
/// add a text
|
||||
void addText(const Base::Vector3f& point, const char * text, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
//@}
|
||||
|
||||
/// clear the string buffer
|
||||
void clear();
|
||||
|
||||
/** @name write the result */
|
||||
//@{
|
||||
/// sends the result to the log and gui
|
||||
void saveToLog();
|
||||
/// save the result to a file (*.iv)
|
||||
void saveToFile(const char* FileName);
|
||||
//@}
|
||||
|
||||
private:
|
||||
/// the result string
|
||||
std::stringstream result;
|
||||
|
||||
bool bStartEndOpen;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class does basically the same as Builder3D except that it writes the data
|
||||
* directly into a given stream without buffering the output data in a string stream.
|
||||
@@ -322,6 +234,8 @@ public:
|
||||
void endPoints();
|
||||
/// add an SoPointSet node
|
||||
void addPointSet();
|
||||
/// add a single point (without startPoints() & endPoints() )
|
||||
void addSinglePoint(const Base::Vector3f& point, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
//@}
|
||||
|
||||
/** @name Normal handling */
|
||||
@@ -393,6 +307,57 @@ private:
|
||||
int indent;
|
||||
};
|
||||
|
||||
/** A Builder class for 3D representations on App level
|
||||
* On the application level nothing is known of the visual representation of data.
|
||||
* Nevertheless it's often needed to see some 3D information, e.g. points, directions,
|
||||
* when you program or debug an algorithm. Builder3D was made for this specific purpose.
|
||||
* This class allows you to easily build up a 3D representation of some mathematical and
|
||||
* algorithm internals. You can save this representation to a file and view it in an
|
||||
* Inventor viewer, or send it to the log. In the case of using the log and a debug
|
||||
* FreeCAD the representation will be loaded into the active viewer.
|
||||
* \par
|
||||
* The workflow goes as follows: Create the a Builder3D object and call the methods
|
||||
* to insert the graphical elements. After that call either saveToLog() or saveToFile().
|
||||
* \par
|
||||
* Usage:
|
||||
* \code
|
||||
Base::Builder3D log3D;
|
||||
for ( unsigned long i=0; i<pMesh->CountPoints(); i++ )
|
||||
{
|
||||
log3D.addSinglePoint(pMesh->GetPoint(i));
|
||||
log3D.addText(pMesh->GetPoint(i),"Point");
|
||||
...
|
||||
}
|
||||
log3D.saveToLog();
|
||||
* \endcode
|
||||
* \see Base::ConsoleSingleton
|
||||
*/
|
||||
class BaseExport Builder3D : public InventorBuilder
|
||||
{
|
||||
public:
|
||||
Builder3D();
|
||||
virtual ~Builder3D();
|
||||
|
||||
/** @name point set handling */
|
||||
//@{
|
||||
//@}
|
||||
|
||||
/// clear the string buffer
|
||||
void clear();
|
||||
|
||||
/** @name write the result */
|
||||
//@{
|
||||
/// sends the result to the log and gui
|
||||
void saveToLog();
|
||||
/// save the result to a file (*.iv)
|
||||
void saveToFile(const char* FileName);
|
||||
//@}
|
||||
|
||||
private:
|
||||
/// the result string
|
||||
std::stringstream result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads an OpenInventor file.
|
||||
* @author Werner Mayer
|
||||
|
||||
Reference in New Issue
Block a user