Files
create/src/Mod/Mesh/Gui/SoFCMeshObject.h
2024-11-21 18:30:22 +01:00

311 lines
10 KiB
C++

/***************************************************************************
* Copyright (c) 2006 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef MESHGUI_SOFCMESHOBJECT_H
#define MESHGUI_SOFCMESHOBJECT_H
#include <Inventor/elements/SoReplacedElement.h>
#include <Inventor/fields/SoSFUInt32.h>
#include <Inventor/fields/SoSFVec3f.h>
#include <Inventor/fields/SoSFVec3s.h>
#include <Inventor/fields/SoSField.h>
#include <Inventor/nodes/SoShape.h>
#include <Mod/Mesh/App/Mesh.h>
using GLuint = unsigned int;
using GLint = int;
using GLfloat = float;
namespace MeshCore
{
class MeshFacetGrid;
}
namespace MeshGui
{
// NOLINTBEGIN(cppcoreguidelines-special-member-functions,cppcoreguidelines-virtual-class-destructor)
class MeshGuiExport SoSFMeshObject: public SoSField
{
using inherited = SoSField;
SO_SFIELD_HEADER(SoSFMeshObject,
Base::Reference<const Mesh::MeshObject>,
Base::Reference<const Mesh::MeshObject>)
public:
static void initClass();
SoSFMeshObject(const SoSFMeshObject&) = delete;
};
// -------------------------------------------------------
class MeshGuiExport SoFCMeshObjectElement: public SoReplacedElement
{
using inherited = SoReplacedElement;
SO_ELEMENT_HEADER(SoFCMeshObjectElement);
public:
static void initClass();
void init(SoState* state) override;
static void set(SoState* const state, SoNode* const node, const Mesh::MeshObject* const mesh);
static const Mesh::MeshObject* get(SoState* const state);
static const SoFCMeshObjectElement* getInstance(SoState* state);
void print(FILE* file) const override;
protected:
~SoFCMeshObjectElement() override;
private:
const Mesh::MeshObject* mesh {};
};
// -------------------------------------------------------
class MeshGuiExport SoFCMeshPickNode: public SoNode
{
using inherited = SoNode;
SO_NODE_HEADER(SoFCMeshPickNode);
public:
static void initClass();
SoFCMeshPickNode();
void notify(SoNotList*) override;
SoSFMeshObject mesh; // NOLINT
void rayPick(SoRayPickAction* action) override;
void pick(SoPickAction* action) override;
protected:
~SoFCMeshPickNode() override;
private:
MeshCore::MeshFacetGrid* meshGrid {nullptr};
};
// -------------------------------------------------------
class MeshGuiExport SoFCMeshGridNode: public SoNode
{
using inherited = SoNode;
SO_NODE_HEADER(SoFCMeshGridNode);
public:
static void initClass();
SoFCMeshGridNode();
void GLRender(SoGLRenderAction* action) override;
SoSFVec3f minGrid;
SoSFVec3f maxGrid;
SoSFVec3s lenGrid;
protected:
~SoFCMeshGridNode() override;
};
// -------------------------------------------------------
class MeshGuiExport SoFCMeshObjectNode: public SoNode
{
using inherited = SoNode;
SO_NODE_HEADER(SoFCMeshObjectNode);
public:
static void initClass();
SoFCMeshObjectNode();
SoSFMeshObject mesh;
void doAction(SoAction* action) override;
void GLRender(SoGLRenderAction* action) override;
void callback(SoCallbackAction* action) override;
void getBoundingBox(SoGetBoundingBoxAction* action) override;
void pick(SoPickAction* action) override;
void getPrimitiveCount(SoGetPrimitiveCountAction* action) override;
protected:
~SoFCMeshObjectNode() override;
};
/**
* class SoFCMeshObjectShape
* \brief The SoFCMeshObjectShape class is designed to render huge meshes.
*
* The SoFCMeshObjectShape is an Inventor shape node that is designed to render huge meshes.
* If the mesh exceeds a certain number of triangles and the user does some intersections
* (e.g. moving, rotating, zooming, spinning, etc.) with the mesh then the GLRender() method
* renders only the gravity points of a subset of the triangles.
* If there is no user interaction with the mesh then all triangles are rendered.
* The limit of maximum allowed triangles can be specified in \a renderTriangleLimit, the
* default value is set to 100.000.
*
* The GLRender() method checks the status of the SoFCInteractiveElement to decide to be in
* interactive mode or not.
* To take advantage of this facility the client programmer must set the status of the
* SoFCInteractiveElement to \a true if there is a user interaction and set the status to
* \a false if not. This can be done e.g. in the actualRedraw() method of the viewer.
*
* @author Werner Mayer
*/
class MeshGuiExport SoFCMeshObjectShape: public SoShape
{
using inherited = SoShape;
SO_NODE_HEADER(SoFCMeshObjectShape);
public:
static void initClass();
SoFCMeshObjectShape();
unsigned int renderTriangleLimit; // NOLINT
protected:
void doAction(SoAction* action) override;
void GLRender(SoGLRenderAction* action) override;
void computeBBox(SoAction* action, SbBox3f& box, SbVec3f& center) override;
void getPrimitiveCount(SoGetPrimitiveCountAction* action) override;
void rayPick(SoRayPickAction* action) override;
void generatePrimitives(SoAction* action) override;
SoDetail* createTriangleDetail(SoRayPickAction* action,
const SoPrimitiveVertex* v1,
const SoPrimitiveVertex* v2,
const SoPrimitiveVertex* v3,
SoPickedPoint* pp) override;
// Force using the reference count mechanism.
~SoFCMeshObjectShape() override;
private:
enum Binding
{
OVERALL = 0,
PER_FACE_INDEXED,
PER_VERTEX_INDEXED,
NONE = OVERALL
};
private:
void notify(SoNotList* node) override;
Binding findMaterialBinding(SoState* const state) const;
// Draw faces
void drawFaces(const Mesh::MeshObject*,
SoMaterialBundle* mb,
Binding bind,
SbBool needNormals,
SbBool ccw) const;
void drawPoints(const Mesh::MeshObject*, SbBool needNormals, SbBool ccw) const;
unsigned int countTriangles(SoAction* action) const;
void startSelection(SoAction* action, const Mesh::MeshObject*);
void stopSelection(SoAction* action, const Mesh::MeshObject*);
void renderSelectionGeometry(const Mesh::MeshObject*);
void generateGLArrays(SoState* state);
void renderFacesGLArray(SoGLRenderAction* action);
void renderCoordsGLArray(SoGLRenderAction* action);
private:
GLuint* selectBuf {nullptr};
GLfloat modelview[16] {};
GLfloat projection[16] {};
// Vertex array handling
std::vector<int32_t> index_array;
std::vector<float> vertex_array;
SbBool updateGLArray {false};
};
class MeshGuiExport SoFCMeshSegmentShape: public SoShape
{
using inherited = SoShape;
SO_NODE_HEADER(SoFCMeshSegmentShape);
public:
static void initClass();
SoFCMeshSegmentShape();
SoSFUInt32 index;
unsigned int renderTriangleLimit;
protected:
void GLRender(SoGLRenderAction* action) override;
void computeBBox(SoAction* action, SbBox3f& box, SbVec3f& center) override;
void getPrimitiveCount(SoGetPrimitiveCountAction* action) override;
void generatePrimitives(SoAction* action) override;
// Force using the reference count mechanism.
~SoFCMeshSegmentShape() override = default;
private:
enum Binding
{
OVERALL = 0,
PER_FACE_INDEXED,
PER_VERTEX_INDEXED,
NONE = OVERALL
};
private:
Binding findMaterialBinding(SoState* const state) const;
// Draw faces
void drawFaces(const Mesh::MeshObject*,
SoMaterialBundle* mb,
Binding bind,
SbBool needNormals,
SbBool ccw) const;
void drawPoints(const Mesh::MeshObject*, SbBool needNormals, SbBool ccw) const;
};
class MeshGuiExport SoFCMeshObjectBoundary: public SoShape
{
using inherited = SoShape;
SO_NODE_HEADER(SoFCMeshObjectBoundary);
public:
static void initClass();
SoFCMeshObjectBoundary();
protected:
void GLRender(SoGLRenderAction* action) override;
void computeBBox(SoAction* action, SbBox3f& box, SbVec3f& center) override;
void getPrimitiveCount(SoGetPrimitiveCountAction* action) override;
void generatePrimitives(SoAction* action) override;
// Force using the reference count mechanism.
~SoFCMeshObjectBoundary() override = default;
private:
void drawLines(const Mesh::MeshObject*) const;
};
// NOLINTEND(cppcoreguidelines-special-member-functions,cppcoreguidelines-virtual-class-destructor)
} // namespace MeshGui
#endif // MESHGUI_SOFCMESHOBJECT_H