#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <geom/Database.h>
#include <geom/Entity.h>
#include <geom/EntityList.h>
#include <geom/NativeFileWriter.h>
#include <nmb/Edge.h>
#include <nmb/Model.h>
#include <nmb/NativeTopologyReader.h>
#include <nmb/Vertex.h>
#include <nmb/nmbcrvassemble.h>
#include <nmb/nmbcrvintegrity.h>
#include <nmb/nmbtopology.h>
#include <vmath/Base.h>
#include <vmath/Error.h>
#include <vmath/memory.h>
#include <vmath/polynomial.h>
#include <vmath/tolerance.h>
#define CHECK_INTEGRITY TRUE
static Boolean SummarizeModel (const Model *model, const Int32 Index)
{
Edge **Edges;
Vertex **Vertices;
Int32 i, NumFaces, NumEdges, NumVertices;
Int32 NumWireEdges, NumLaminaEdges, NumManifoldEdges, NumNonmanifoldEdges;
Int32 NumWireVertices, NumLaminaVertices, NumManifoldVertices, NumNonmanifoldVertices;
char TopolTypeString[80];
char TopolType, EdgeTopolType, VertexTopolType;
NMBT_Model_Inquire_Faces (model, NULL, &NumFaces);
NMBT_Model_Inquire_Edges (model, &Edges, &NumEdges);
NMBT_Model_Inquire_Vertices (model, &Vertices, &NumVertices);
fprintf (stdout, "==> New Model #%ld <==\n", Index);
fprintf (stdout, "Number of faces\t\t: %12ld\n", NumFaces);
fprintf (stdout, "Number of edges\t\t: %12ld\n", NumEdges);
fprintf (stdout, "Number of vertices\t: %12ld\n", NumVertices);
NMBT_Model_Inquire_TopologicalType (model, &TopolType);
switch (TopolType) {
case NMBT_MODEL_TOPOL_TYPE_WIRE:
sprintf (TopolTypeString, "wire");
break;
case NMBT_MODEL_TOPOL_TYPE_SHEET:
sprintf (TopolTypeString, "sheet");
break;
case NMBT_MODEL_TOPOL_TYPE_MANIFOLD:
sprintf (TopolTypeString, "manifold");
break;
case NMBT_MODEL_TOPOL_TYPE_NONMANIFOLD:
sprintf (TopolTypeString, "non-manifold");
break;
}
fprintf (stdout, "Topological type\t: %s\n", TopolTypeString);
NumWireEdges = NumLaminaEdges = NumManifoldEdges = NumNonmanifoldEdges = 0;
for (i = 0; i < NumEdges; i++) {
NMBT_Edge_Inquire_TopologicalType (Edges[i], &EdgeTopolType);
switch (EdgeTopolType) {
case NMBT_TOPOL_TYPE_WIRE:
NumWireEdges++;
break;
case NMBT_TOPOL_TYPE_LAMINA:
NumLaminaEdges++;
break;
case NMBT_TOPOL_TYPE_MANIFOLD:
NumManifoldEdges++;
break;
case NMBT_TOPOL_TYPE_NONMANIFOLD:
NumNonmanifoldEdges++;
break;
}
}
MEM_ArrayFree ((void**)&Edges);
if (NumWireEdges)
fprintf (stdout, " # of wire edges\t: %12ld\n", NumWireEdges);
if (NumLaminaEdges)
fprintf (stdout, " # of lamina edges\t: %12ld\n", NumLaminaEdges);
if (NumManifoldEdges)
fprintf (stdout, " # of manifold edges\t: %12ld\n", NumManifoldEdges);
if (NumNonmanifoldEdges)
fprintf (stdout, " # of non-man edges\t: %12ld\n", NumNonmanifoldEdges);
NumWireVertices = NumLaminaVertices = NumManifoldVertices = NumNonmanifoldVertices = 0;
for (i = 0; i < NumVertices; i++) {
NMBT_Vertex_Inquire_TopologicalType (Vertices[i], &VertexTopolType);
switch (VertexTopolType) {
case NMBT_TOPOL_TYPE_WIRE:
NumWireVertices++;
break;
case NMBT_TOPOL_TYPE_LAMINA:
NumLaminaVertices++;
break;
case NMBT_TOPOL_TYPE_MANIFOLD:
NumManifoldVertices++;
break;
case NMBT_TOPOL_TYPE_NONMANIFOLD:
NumNonmanifoldVertices++;
break;
}
}
MEM_ArrayFree ((void**)&Vertices);
if (NumWireVertices)
fprintf (stdout, " # of wire vertices\t: %12ld\n", NumWireVertices);
if (NumLaminaVertices)
fprintf (stdout, " # of lamina vertices\t: %12ld\n", NumLaminaVertices);
if (NumManifoldVertices)
fprintf (stdout, " # of manifold vertices: %12ld\n", NumManifoldVertices);
if (NumNonmanifoldVertices)
fprintf (stdout, " # of non-man vertices\t: %12ld\n", NumNonmanifoldVertices);
return (TRUE);
}
static Boolean AssembleModels (Database *const Geom, const Real64 EdgeTolerance)
{
EntityList Models, Assemblies, UnusedGeometry;
Entity *DependentChild;
Int32 i;
ERR_type LocalError, Error = ERR_no_errors;
Geom->Inquire_Entities (ENT_class_curved_model,
&Models);
for (i = 0; i < Models.numEntities; i++) {
#if CHECK_INTEGRITY
if ((LocalError = NMBCI_Model_Check_Integrity ((Model*)Models.entityList[i])) != ERR_no_errors)
Error = LocalError;
#endif
SummarizeModel ((Model*)Models.entityList[i], i);
}
if (Error != ERR_no_errors)
return (Error == ERR_no_errors);
if ((LocalError = NMBCASS_Model_Assemble (&Models, EdgeTolerance,
FALSE, TRUE, &Assemblies, &UnusedGeometry)) != ERR_no_errors) {
fprintf (stderr, "WARNING: NMBCASS_Model_Assemble: Failure assembling models (error #%ld)...\n", (Int32)LocalError);
Error = LocalError;
}
if (UnusedGeometry.numEntities > 0) {
Int32 NumDeleted = 0;
for (i = 0; i < UnusedGeometry.numEntities; i++)
if (UnusedGeometry.entityList[i]->Inquire_Deletable (&DependentChild)) {
NumDeleted++;
UnusedGeometry.entityList[i]->Delete ();
}
if (NumDeleted > 0)
printf ("NOTE: Deleted %ld unused support curves...\n", NumDeleted);
}
for (i = 0; i < Assemblies.numEntities; i++) {
#if CHECK_INTEGRITY
if ((LocalError = NMBCI_Model_Check_Integrity ((Model*)Assemblies.entityList[i])) != ERR_no_errors)
Error = LocalError;
#endif
SummarizeModel ((Model*)Assemblies.entityList[i], i);
}
if ((LocalError = Geom->Attach_Entities (&Assemblies)) != ERR_no_errors) {
fprintf (stderr, "WARNING: Database::Attach_Entities: Failure attaching models (error #%ld)...\n", (Int32)LocalError);
Error = LocalError;
}
return (Error == ERR_no_errors);
}
int main (int argc, char **argv)
{
Database *DB = NULL;
Real64 EdgeTolerance = TOL_GetSamePointTol ();
Real64 secs;
Int32 i, ci, cf;
char FileName[256] = "";
char NMBFileName[] = "modelassemble.out.nmb";
Int32 ErrorCode = 0;
for (i = 1; i < argc; i++)
if (strcmp (argv[i], "-h") == 0) {
printf ("Usage: %s [-t xx.xx] [filename]\n", argv[0]);
return (0);
} else if (strcmp (argv[i], "-t") == 0)
EdgeTolerance = atof (argv[++i]);
else if (i == (argc - 1))
strcpy (FileName, argv[i]);
if (!(DB = new Database ()))
return (-1);
if (strlen (FileName) == 0)
strcpy (FileName, "../data/faceface.test.nmb");
printf ("Reading %s...\n", FileName);
ci = clock();
if (NativeTopologyReader::Read (FileName, DB) != ERR_no_errors)
return (1);
printf ("Finished reading file...\n");
cf = clock();
secs = (Real64)(cf - ci)/(Real64)CLOCKS_PER_SEC;
fprintf (stdout, "Elapsed CPU Time (secs) = %.2f\n", secs);
printf ("Assembling models...\n");
ci = cf;
if (!AssembleModels (DB, EdgeTolerance))
ErrorCode = 3;
printf ("Finished assembling models...\n");
cf = clock();
secs = (Real64)(cf - ci)/(Real64)CLOCKS_PER_SEC;
fprintf (stdout, "Elapsed CPU Time (secs) = %.2f\n", secs);
printf ("Writing database to %s...\n", NMBFileName);
ci = cf;
if (NativeFileWriter::Write (NMBFileName, DB) == ERR_no_errors)
printf ("Write succeeded...\n");
else {
printf ("Write failed...\n");
ErrorCode = 2;
}
cf = clock();
secs = (Real64)(cf - ci)/(Real64)CLOCKS_PER_SEC;
fprintf (stdout, "Elapsed CPU Time (secs) = %.2f\n", secs);
printf ("Destroying database and its contents...\n");
ci = cf;
if (DB->Delete () != ERR_no_errors)
ErrorCode = 5;
printf ("Finished destroying database and its contents...\n");
cf = clock();
secs = (Real64)(cf - ci)/(Real64)CLOCKS_PER_SEC;
fprintf (stdout, "Elapsed CPU Time (secs) = %.2f\n", secs);
POLY_FreeSystem ();
return (ErrorCode);
}