preamble
Osg needs to open the model file, but encountered the k model file which shows the dynamics simulation, the .k file is a kind of file which describes the material properties, such as density, elastic modulus, etc. This model file is not a regular intermediate open format, and can't be directly supported, it needs to be customized to parse and rebuild the three-dimensional model.
Demo
The actual very flow, as the video to gif causes parts to look like they don't work:
Interaction Fluency Test
The actual research and development needs to be carried out with different strategies to optimize the model display without affecting the visual perception of the premise, this test directly copy multiple model loading:
-
More than 1.72 million quads, silky smooth
-
More than 3.44 million quads, silky smooth
-
With over 5.18 million quads, it's starting to get slightly laggy
-
With over 6.91 million quads, it's starting to get even less sharp
At this point doubling on the loading scene crashes, this crash confirms that the code is fine, it's the runtime memory that's larger, increase the runtime memory configuration:
QMAKE_LFLAGS_WINDOWS += /LARGEADDRESSAWARE
Running successfully, the interaction is a little more stuck.
Bigger doesn't work again:
take note of
The analysis is parsed for this file and may contain incomplete data format keywords.
The actual encounters are *TITLE, *PART, *ELEMENT_SHELL, *NODE, *END.
(PS: I'll add to this in a separate chapter if I come across it on a future project.)
k-file
skim through
A .k file is a file that describes the properties of a material, such as density, modulus of elasticity, and so on.
Open its software LS-DYNA and LSPREPOST
- LS-DYNA
LS-DYNA program (the latest version 17.2) is a full-featured program for geometric nonlinearities (large displacements, large rotations and large strains), material nonlinearities (more than 140 kinds of material dynamic models) and contact nonlinearities (more than 50 kinds). It is mainly based on Lagrange algorithm, and also has ALE and Euler algorithm; mainly based on explicit solving, and also has implicit solving function; mainly based on structural analysis, and also has thermal analysis and fluid-structure coupling function; mainly based on nonlinear dynamic analysis, and also has static analysis function (such as prestressing calculation before dynamic analysis, and rebound calculation after press forming of thin plate); and it is a general-purpose structural analysis program which is a combination of military and civilian use. Analysis of nonlinear finite element program, is the originator and pioneer of explicit dynamics program. - LSPREPOST
lsprepost is a suite of advanced finite element pre- and post-processing software developed specifically for LS-DYNA, with a January 1, 1976 on-line date.
Overview of the contents of the document
An overall overview of the document is given below:
The above knowledge is divided into six keywords, split into five regions, with the following attribution:
Keywords: *KEYWORK
Keywords: *TITLE
Keywords: *PART
PART keywords to define components and their associated characteristics
The first line is the title attribute, for the title, which has no real meaning.
Keywords: *ELEMENT_SHELL
The SECTION series of keywords specifies the cell algorithm used, the integral division rule and various geometrical parameters (thickness of the shell cell, cross-section information parameters of the beam cell, etc.) for different cell types, or if the correspondingThe SECTION key field to define the algorithm and parameters of the unit.
*SECTION_SEHLL defines the properties of a single shell cell. These properties are critical for simulations such as automotive crashes, aerospace structures, and any simulation involving the dynamic response of thin-shell structures. However, the details and format of the ELEMENT_SHELL attributes in the K-file specifically may vary depending on the version of LS-DYNA and the specific application.
Keywords: *NODE
The *NODE keyword defines each node of the structural model and its coordinates and constraints in the overall Cartesian coordinate system, and the key field contains the following variable information:
Then the parts correspond to the node by index correspondence:
Just parse the file.
Keywords: *END
Indicates the end of the file.
Test loading K-files
Demo key source code
model structure
// Model Structures
struct Element_Shell // *ELEMENT_SHELL
{
Element_Shell() {
}
qint64 eid; // Unit id
qint64 pid; // Material id
qint64 n1; // Node 1, defining the geometry
qint64 n2; // Node 2, defining the geometry
qint64 n3; // Node 3, defining the geometry
qint64 n4; // Node 4, defining the geometry
qint64 n5; // Thickness, extra nodes are meaningless in the standard LS-DYNA quadrilateral shell cell definition.
qint64 n6; // Integral points, extra nodes are meaningless in the standard LS-DYNA quadrilateral shell cell definition.
qint64 n7; // Extra nodes are meaningless in the standard LS-DYNA quadrilateral shell cell definition.
qint64 n8; // Extra nodes have no meaning in the standard LS-DYNA quadrilateral shell unit definition.
};
struct Part // *PART
{
Part() {
}
qint64 pid; // Part id number, unique
qint64 secid; // The id number of the section defined with the *section keyword.
QList<Element_Shell> listElementShell; // Part slice element
qint64 mid; // Material number of the component
qint64 eosid; // The equation of state number of the material to which the part belongs, defined by the *EOS keyword
qint64 hgid; // Hourglass or volumetric viscosity parameter number, defined by the *HOURGLASS keyword; taking 0 means that the default value will be used:
qint64 grav; // Valid for entity units only, take 0 to indicate gravity initialization for all PARTs, take 1 to indicate initialization for current material only
qint64 adpopt; // Identifies whether the part uses adaptive meshing, 0 means no
qint64 tmid; // Identifies if the part uses adaptive meshing, 0 means no.
};
struct Node {
Node() {
}
qint64 nid; // Node number, unique
double x; // 3D x-coordinates (global)
double y; // 3D y-coordinate (global)
double z; // 3D z-coordinate (global)
int tc; // Constrained state of the translational degrees of freedom, enumeration: 0 - no translational constraints, 1 - translational constraints in the x-direction, 2 - translational constraints in the y-direction.
int rc; // Constraint state of the rotational degrees of freedom, enumerated values: 0 - no rotation constraint, 1 - rotation constraint in X direction, 2 - rotation constraint in Y direction.
};
struct K_Mode
{
K_Mode() {}
QList<Part> listPart;
QList<Node> listNode;
QHash<int, Node> hashNid2Node;
};
Drawing section
osg::ref_ptr<osg::Group> pGroup = new osg::Group;
// Drawing
{
for(int partIndex = 0; partIndex < kMode.listPart.size(); partIndex++)
{
// Create an object where the user keeps geometry information
osg::ref_ptr<osg::Geometry> pGeometry = new osg::Geometry;
// Create an array of four vertices
osg::ref_ptr<osg::Vec3Array> pVec3Array = new osg::Vec3Array;
// Add four vertices
pGeometry->setVertexArray(pVec3Array.get());
// Create four colors of data
osg::ref_ptr<osg::Vec4Array> pVec4Array = new osg::Vec4Array;
// Add four colors
pGeometry->setColorArray(pVec4Array.get());
// Bind the color
pGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
double r, g, b;
r = qrand() % 100 * 1.0f / 100;
g = qrand() % 100 * 1.0f / 100;
b = qrand() % 100 * 1.0f / 100;
for(int elementShellIndex = 0; elementShellIndex < kMode.listPart.at(partIndex).listElementShell.size(); elementShellIndex++)
{
// x y z
#if 0
pVec3Array->push_back(osg::Vec3( 1.0, 0.0, 0.0));
pVec3Array->push_back(osg::Vec3( 3.0, 0.0, 0.0));
pVec3Array->push_back(osg::Vec3( 3.0, 0.0, 1.0));
pVec3Array->push_back(osg::Vec3( 1.0, 0.0, 1.0));
#endif
pVec3Array->push_back(osg::Vec3(kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n1).x,
kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n1