mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-26 10:19:45 +03:00
The copying permission statements at the beginning of source files updated to refer to LGPL. Copyright dates extended till 2014 in advance.
846 lines
29 KiB
C++
846 lines
29 KiB
C++
// Created on: 2000-06-16
|
|
// Copyright (c) 2000-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and / or modify it
|
|
// under the terms of the GNU Lesser General Public version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#define TRACE 0
|
|
|
|
#include <Graphic3d_ArrayOfPrimitives.ixx>
|
|
#include <Standard.hxx>
|
|
#include <TCollection_AsciiString.hxx>
|
|
#include <OSD_Environment.hxx>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
Graphic3d_ArrayOfPrimitives :: Graphic3d_ArrayOfPrimitives (
|
|
const Graphic3d_TypeOfPrimitiveArray aType,
|
|
const Standard_Integer maxVertexs,
|
|
const Standard_Integer maxBounds,
|
|
const Standard_Integer maxEdges,
|
|
const Standard_Boolean hasVNormals,
|
|
const Standard_Boolean hasVColors,
|
|
const Standard_Boolean hasFColors,
|
|
const Standard_Boolean hasVTexels,
|
|
const Standard_Boolean hasEdgeInfos )
|
|
: myMaxBounds(0),myMaxVertexs(0),myMaxEdges(0)
|
|
{
|
|
const Standard_Integer size = sizeof(CALL_DEF_PARRAY);
|
|
Standard_Integer format = MVERTICE;
|
|
if( hasVNormals ) format |= MVNORMAL;
|
|
if( hasVColors ) format |= MVCOLOR;
|
|
if( hasVTexels ) format |= MVTEXEL;
|
|
|
|
myPrimitiveArray = (Graphic3d_PrimitiveArray) Standard::Allocate(size);
|
|
memset ( myPrimitiveArray, 0, size );
|
|
|
|
if( maxVertexs > 0){
|
|
myPrimitiveArray->vertices = (TEL_POINT*) Standard::Allocate(maxVertexs *sizeof(TEL_POINT));
|
|
memset ( myPrimitiveArray->vertices, 0, maxVertexs *sizeof(TEL_POINT));
|
|
}
|
|
|
|
if( hasVNormals ){
|
|
myPrimitiveArray->vnormals = (TEL_POINT*) Standard::Allocate(sizeof(TEL_POINT) * maxVertexs);
|
|
memset ( myPrimitiveArray->vnormals, 0, sizeof(TEL_POINT) * maxVertexs);
|
|
}
|
|
|
|
if( hasVColors ){
|
|
myPrimitiveArray->vcolours = (Tint*) Standard::Allocate(maxVertexs *sizeof(Tint));
|
|
memset ( myPrimitiveArray->vcolours, 0, sizeof(Tint) * maxVertexs);
|
|
}
|
|
|
|
if( hasVTexels ){
|
|
myPrimitiveArray->vtexels = (TEL_TEXTURE_COORD*) Standard::Allocate(maxVertexs *sizeof(TEL_TEXTURE_COORD));
|
|
memset ( myPrimitiveArray->vtexels, 0, sizeof(TEL_TEXTURE_COORD) * maxVertexs);
|
|
}
|
|
|
|
if( hasFColors && (maxBounds > 0) ){
|
|
myPrimitiveArray->fcolours = (TEL_COLOUR*) Standard::Allocate(maxBounds *sizeof(TEL_COLOUR));
|
|
memset ( myPrimitiveArray->fcolours, 0, sizeof(TEL_COLOUR) * maxBounds);
|
|
}
|
|
|
|
if( maxBounds > 0 ){
|
|
myPrimitiveArray->bounds = (Tint*) Standard::Allocate(maxBounds *sizeof(Tint));
|
|
memset ( myPrimitiveArray->bounds, 0, maxBounds *sizeof(Tint));
|
|
}
|
|
|
|
if( maxEdges > 0 ){
|
|
myPrimitiveArray->edges = (Tint*) Standard::Allocate(maxEdges *sizeof(Tint));
|
|
memset ( myPrimitiveArray->edges, 0, maxEdges *sizeof(Tint));
|
|
}
|
|
|
|
if( hasEdgeInfos && (maxEdges > 0) ){
|
|
myPrimitiveArray->edge_vis = (Tchar*)Standard::Allocate(maxEdges *sizeof(Tchar));
|
|
memset ( myPrimitiveArray->edge_vis, 0, maxEdges *sizeof(Tchar));
|
|
}
|
|
|
|
myPrimitiveArray->keys = NULL;
|
|
myMaxVertexs = maxVertexs;
|
|
myMaxBounds = maxBounds;
|
|
myMaxEdges = maxEdges;
|
|
myPrimitiveArray->type = (TelPrimitivesArrayType) aType;
|
|
myPrimitiveArray->format = format;
|
|
myPrimitiveArray->num_bounds = 0;
|
|
myPrimitiveArray->num_vertexs = 0;
|
|
myPrimitiveArray->num_edges = 0;
|
|
}
|
|
|
|
void Graphic3d_ArrayOfPrimitives::Destroy ()
|
|
{
|
|
if( myPrimitiveArray ) {
|
|
if( myPrimitiveArray->vertices ){
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray->vertices );
|
|
myPrimitiveArray->vertices = 0;
|
|
}
|
|
|
|
if( myPrimitiveArray->vnormals ){
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray->vnormals );
|
|
myPrimitiveArray->vnormals = 0;
|
|
}
|
|
|
|
if( myPrimitiveArray->vcolours ){
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray->vcolours );
|
|
myPrimitiveArray->vcolours = 0;
|
|
}
|
|
|
|
if( myPrimitiveArray->vtexels ){
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray->vtexels );
|
|
myPrimitiveArray->vtexels = 0;
|
|
}
|
|
|
|
if( myPrimitiveArray->fcolours ){
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray->fcolours );
|
|
myPrimitiveArray->fcolours = 0;
|
|
}
|
|
|
|
if( myPrimitiveArray->bounds ){
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray->bounds );
|
|
myPrimitiveArray->bounds = 0;
|
|
}
|
|
|
|
if( myPrimitiveArray->edges ){
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray->edges );
|
|
myPrimitiveArray->edges = 0;
|
|
}
|
|
|
|
if( myPrimitiveArray->edge_vis ){
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray->edge_vis );
|
|
myPrimitiveArray->edge_vis = 0;
|
|
}
|
|
|
|
Standard::Free( (Standard_Address&)myPrimitiveArray );
|
|
#if TRACE > 0
|
|
cout << " Graphic3d_ArrayOfPrimitives::Destroy()" << endl;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z)
|
|
{
|
|
if( !myPrimitiveArray ) return 0;
|
|
const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
|
|
SetVertice(index,X,Y,Z);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const Quantity_Color& aColor)
|
|
{
|
|
const Standard_Integer index = AddVertex(aVertice);
|
|
Standard_Real r,g,b;
|
|
aColor.Values(r,g,b,Quantity_TOC_RGB);
|
|
SetVertexColor(index,r,g,b);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const Standard_Integer aColor)
|
|
{
|
|
const Standard_Integer index = AddVertex(aVertice);
|
|
SetVertexColor(index,aColor);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
|
|
const Standard_ShortReal NX, const Standard_ShortReal NY, const Standard_ShortReal NZ)
|
|
{
|
|
if( !myPrimitiveArray ) return 0;
|
|
const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
|
|
SetVertice(index,X,Y,Z);
|
|
SetVertexNormal(index,NX,NY,NZ);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice,
|
|
const gp_Dir& aNormal,
|
|
const Quantity_Color& aColor)
|
|
{
|
|
const Standard_Integer index = AddVertex(aVertice,aNormal);
|
|
Standard_Real r,g,b;
|
|
aColor.Values(r,g,b,Quantity_TOC_RGB);
|
|
SetVertexColor(index,r,g,b);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice,
|
|
const gp_Dir& aNormal,
|
|
const Standard_Integer aColor)
|
|
{
|
|
const Standard_Integer index = AddVertex(aVertice,aNormal);
|
|
SetVertexColor(index,aColor);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
|
|
const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
|
|
const Standard_ShortReal TX, const Standard_ShortReal TY)
|
|
{
|
|
if( !myPrimitiveArray ) return 0;
|
|
const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
|
|
SetVertice(index,X,Y,Z);
|
|
SetVertexTexel(index,TX,TY);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
|
|
const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
|
|
const Standard_ShortReal NX, const Standard_ShortReal NY, const Standard_ShortReal NZ,
|
|
const Standard_ShortReal TX, const Standard_ShortReal TY)
|
|
{
|
|
if( !myPrimitiveArray ) return 0;
|
|
const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
|
|
SetVertice(index,X,Y,Z);
|
|
SetVertexNormal(index,NX,NY,NZ);
|
|
SetVertexTexel(index,TX,TY);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber)
|
|
{
|
|
Standard_Integer index = 0;
|
|
if( myPrimitiveArray && myPrimitiveArray->bounds ) {
|
|
index = myPrimitiveArray->num_bounds;
|
|
if( index < myMaxBounds ) {
|
|
myPrimitiveArray->bounds[index] = edgeNumber;
|
|
myPrimitiveArray->num_bounds = ++index;
|
|
} else {
|
|
Standard_OutOfRange::Raise(" TOO many BOUNDS");
|
|
}
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber,
|
|
const Quantity_Color& aFColor)
|
|
{
|
|
Standard_Real r,g,b;
|
|
aFColor.Values(r,g,b,Quantity_TOC_RGB);
|
|
return AddBound(edgeNumber,r,g,b);
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber,
|
|
const Standard_Real R,
|
|
const Standard_Real G,
|
|
const Standard_Real B)
|
|
{
|
|
if( !myPrimitiveArray ) return 0;
|
|
Standard_Integer index = myPrimitiveArray->num_bounds;
|
|
if( index >= myMaxBounds ) {
|
|
Standard_OutOfRange::Raise(" TOO many BOUND");
|
|
}
|
|
myPrimitiveArray->bounds[index] = edgeNumber;
|
|
myPrimitiveArray->num_bounds = ++index;
|
|
SetBoundColor(index,R,G,B);
|
|
return index;
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge(const Standard_Integer vertexIndex,
|
|
const Standard_Boolean isVisible)
|
|
{
|
|
if( !myPrimitiveArray ) return 0;
|
|
|
|
Standard_Integer index = myPrimitiveArray->num_edges;
|
|
if( index >= myMaxEdges ) {
|
|
Standard_OutOfRange::Raise(" TOO many EDGE");
|
|
}
|
|
Standard_Integer vindex = vertexIndex-1;
|
|
if( vertexIndex > 0 && vindex < myMaxVertexs ) {
|
|
myPrimitiveArray->edges[index] = vindex;
|
|
if( myPrimitiveArray->edge_vis ) {
|
|
myPrimitiveArray->edge_vis[index] = (Tchar) (isVisible ? 1 : 0);
|
|
}
|
|
myPrimitiveArray->num_edges = ++index;
|
|
} else {
|
|
Standard_OutOfRange::Raise(" BAD EDGE vertex index");
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const gp_Dir& aNormal)
|
|
{
|
|
return Orientate(1,Max(VertexNumber(),EdgeNumber()),aNormal);
|
|
}
|
|
|
|
Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const Standard_Integer aVertexIndex,
|
|
const Standard_Integer aVertexNumber,
|
|
const gp_Dir& aNormal)
|
|
{
|
|
Standard_Boolean somethingHasChange = Standard_False;
|
|
if( myPrimitiveArray && (myPrimitiveArray->num_vertexs > 2) ) {
|
|
Standard_Integer i,j,k=aVertexNumber,n=aVertexIndex-1;
|
|
Standard_ShortReal x,y,z;
|
|
if( myPrimitiveArray->edges ) {
|
|
if( n >= 0 && (n+k) <= myPrimitiveArray->num_edges ) {
|
|
Standard_Integer i1 = myPrimitiveArray->edges[n];
|
|
Standard_Integer i2 = myPrimitiveArray->edges[n+1];
|
|
Standard_Integer i3 = myPrimitiveArray->edges[n+2];
|
|
gp_Pnt p1(myPrimitiveArray->vertices[i1].xyz[0],
|
|
myPrimitiveArray->vertices[i1].xyz[1],
|
|
myPrimitiveArray->vertices[i1].xyz[2]);
|
|
gp_Pnt p2(myPrimitiveArray->vertices[i2].xyz[0],
|
|
myPrimitiveArray->vertices[i2].xyz[1],
|
|
myPrimitiveArray->vertices[i2].xyz[2]);
|
|
gp_Pnt p3(myPrimitiveArray->vertices[i3].xyz[0],
|
|
myPrimitiveArray->vertices[i3].xyz[1],
|
|
myPrimitiveArray->vertices[i3].xyz[2]);
|
|
gp_Vec v21(p1,p2),v31(p1,p3),fn = v21.Crossed(v31);
|
|
if( aNormal.IsOpposite(fn, M_PI / 4.) ) {
|
|
Standard_Integer e; char v;
|
|
for( i=0,j=k-1 ; i<k/2 ; i++,j-- ) {
|
|
e = myPrimitiveArray->edges[n+i];
|
|
myPrimitiveArray->edges[n+i] = myPrimitiveArray->edges[n+j];
|
|
myPrimitiveArray->edges[n+j] = e;
|
|
if( myPrimitiveArray->edge_vis ) {
|
|
v = myPrimitiveArray->edge_vis[n+i];
|
|
myPrimitiveArray->edge_vis[n+i] = myPrimitiveArray->edge_vis[n+j];
|
|
myPrimitiveArray->edge_vis[n+j] = v;
|
|
}
|
|
if( myPrimitiveArray->vnormals ) {
|
|
e = myPrimitiveArray->edges[n+i];
|
|
x = myPrimitiveArray->vnormals[e].xyz[0];
|
|
y = myPrimitiveArray->vnormals[e].xyz[1];
|
|
z = myPrimitiveArray->vnormals[e].xyz[2];
|
|
gp_Vec vn(x,y,z);
|
|
if( aNormal.IsOpposite(vn, M_PI / 4.) ) {
|
|
myPrimitiveArray->vnormals[e].xyz[0] = -x;
|
|
myPrimitiveArray->vnormals[e].xyz[1] = -y;
|
|
myPrimitiveArray->vnormals[e].xyz[2] = -z;
|
|
}
|
|
}
|
|
}
|
|
somethingHasChange = Standard_True;
|
|
}
|
|
} else {
|
|
Standard_OutOfRange::Raise(" BAD EDGE index or number");
|
|
}
|
|
return somethingHasChange;
|
|
}
|
|
|
|
if( n >= 0 && (n+k) <= myPrimitiveArray->num_vertexs ) {
|
|
gp_Pnt p1(myPrimitiveArray->vertices[n].xyz[0],
|
|
myPrimitiveArray->vertices[n].xyz[1],
|
|
myPrimitiveArray->vertices[n].xyz[2]);
|
|
gp_Pnt p2(myPrimitiveArray->vertices[n+1].xyz[0],
|
|
myPrimitiveArray->vertices[n+1].xyz[1],
|
|
myPrimitiveArray->vertices[n+1].xyz[2]);
|
|
gp_Pnt p3(myPrimitiveArray->vertices[n+2].xyz[0],
|
|
myPrimitiveArray->vertices[n+2].xyz[1],
|
|
myPrimitiveArray->vertices[n+2].xyz[2]);
|
|
gp_Vec v21(p1,p2),v31(p1,p3),fn = v21.Crossed(v31);
|
|
if( aNormal.IsOpposite(fn, M_PI / 4.) ) {
|
|
for( i=0,j=k-1 ; i<k/2 ; i++,j-- ) {
|
|
x = myPrimitiveArray->vertices[n+i].xyz[0];
|
|
y = myPrimitiveArray->vertices[n+i].xyz[1];
|
|
z = myPrimitiveArray->vertices[n+i].xyz[2];
|
|
myPrimitiveArray->vertices[n+i].xyz[0] = myPrimitiveArray->vertices[n+j].xyz[0];
|
|
myPrimitiveArray->vertices[n+i].xyz[1] = myPrimitiveArray->vertices[n+j].xyz[1];
|
|
myPrimitiveArray->vertices[n+i].xyz[2] = myPrimitiveArray->vertices[n+j].xyz[2];
|
|
myPrimitiveArray->vertices[n+j].xyz[0] = x;
|
|
myPrimitiveArray->vertices[n+j].xyz[1] = y;
|
|
myPrimitiveArray->vertices[n+j].xyz[2] = z;
|
|
if( myPrimitiveArray->vnormals ) {
|
|
x = myPrimitiveArray->vnormals[n+i].xyz[0];
|
|
y = myPrimitiveArray->vnormals[n+i].xyz[1];
|
|
z = myPrimitiveArray->vnormals[n+i].xyz[2];
|
|
myPrimitiveArray->vnormals[n+i].xyz[0] = myPrimitiveArray->vnormals[n+j].xyz[0];
|
|
myPrimitiveArray->vnormals[n+i].xyz[1] = myPrimitiveArray->vnormals[n+j].xyz[1];
|
|
myPrimitiveArray->vnormals[n+i].xyz[2] = myPrimitiveArray->vnormals[n+j].xyz[2];
|
|
myPrimitiveArray->vnormals[n+j].xyz[0] = x;
|
|
myPrimitiveArray->vnormals[n+j].xyz[1] = y;
|
|
myPrimitiveArray->vnormals[n+j].xyz[2] = z;
|
|
|
|
x = myPrimitiveArray->vnormals[n+i].xyz[0];
|
|
y = myPrimitiveArray->vnormals[n+i].xyz[1];
|
|
z = myPrimitiveArray->vnormals[n+i].xyz[2];
|
|
gp_Vec vn(x,y,z);
|
|
if( aNormal.IsOpposite(vn, M_PI / 4.) ) {
|
|
myPrimitiveArray->vnormals[n+i].xyz[0] = -x;
|
|
myPrimitiveArray->vnormals[n+i].xyz[1] = -y;
|
|
myPrimitiveArray->vnormals[n+i].xyz[2] = -z;
|
|
}
|
|
}
|
|
if( myPrimitiveArray->vcolours ) {
|
|
x = (Standard_ShortReal)myPrimitiveArray->vcolours[n+i];
|
|
myPrimitiveArray->vcolours[n+i] = myPrimitiveArray->vcolours[n+j];
|
|
myPrimitiveArray->vcolours[n+j] = (Tint)x;
|
|
}
|
|
if( myPrimitiveArray->vtexels ) {
|
|
x = myPrimitiveArray->vtexels[n+i].xy[0];
|
|
y = myPrimitiveArray->vtexels[n+i].xy[1];
|
|
myPrimitiveArray->vtexels[n+i].xy[0] = myPrimitiveArray->vtexels[n+j].xy[0];
|
|
myPrimitiveArray->vtexels[n+i].xy[1] = myPrimitiveArray->vtexels[n+j].xy[1];
|
|
myPrimitiveArray->vtexels[n+j].xy[0] = x;
|
|
myPrimitiveArray->vtexels[n+j].xy[1] = y;
|
|
}
|
|
}
|
|
somethingHasChange = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
return somethingHasChange;
|
|
}
|
|
|
|
Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const Standard_Integer aBoundIndex,
|
|
const gp_Dir& aNormal)
|
|
{
|
|
Standard_Boolean somethingHasChange = Standard_False;
|
|
if( myPrimitiveArray && myPrimitiveArray->vertices ) {
|
|
if( myPrimitiveArray->bounds &&
|
|
(aBoundIndex > 0) && (aBoundIndex <= myPrimitiveArray->num_bounds) ) {
|
|
Standard_Integer k,n;
|
|
for( k=n=1 ; k<aBoundIndex ; k++ )
|
|
n += myPrimitiveArray->bounds[k];
|
|
k = myPrimitiveArray->bounds[aBoundIndex-1];
|
|
somethingHasChange = Orientate(n,k,aNormal);
|
|
} else if( myPrimitiveArray->bounds ) {
|
|
Standard_OutOfRange::Raise(" BAD BOUND index");
|
|
} else if( (aBoundIndex > 0) && (aBoundIndex <= ItemNumber()) ) {
|
|
switch( myPrimitiveArray->type ) {
|
|
case TelPointsArrayType:
|
|
case TelPolylinesArrayType:
|
|
case TelSegmentsArrayType:
|
|
break;
|
|
case TelPolygonsArrayType:
|
|
case TelTriangleStripsArrayType:
|
|
case TelTriangleFansArrayType:
|
|
case TelQuadrangleStripsArrayType:
|
|
somethingHasChange = Orientate(1,VertexNumber(),aNormal);
|
|
break;
|
|
case TelTrianglesArrayType:
|
|
somethingHasChange = Orientate(aBoundIndex*3-2,3,aNormal);
|
|
break;
|
|
case TelQuadranglesArrayType:
|
|
somethingHasChange = Orientate(aBoundIndex*4-3,4,aNormal);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
Standard_OutOfRange::Raise(" BAD ITEM index");
|
|
}
|
|
}
|
|
return somethingHasChange;
|
|
}
|
|
|
|
void Graphic3d_ArrayOfPrimitives::SetVertice( const Standard_Integer anIndex,
|
|
const gp_Pnt& aVertice)
|
|
{
|
|
Standard_Real x,y,z;
|
|
aVertice.Coord(x,y,z);
|
|
SetVertice(anIndex,Standard_ShortReal(x),Standard_ShortReal(y),Standard_ShortReal(z));
|
|
}
|
|
|
|
void Graphic3d_ArrayOfPrimitives::SetVertexColor( const Standard_Integer anIndex,
|
|
const Quantity_Color& aColor)
|
|
{
|
|
Standard_Real r,g,b;
|
|
aColor.Values(r,g,b,Quantity_TOC_RGB);
|
|
SetVertexColor(anIndex,r,g,b);
|
|
}
|
|
|
|
void Graphic3d_ArrayOfPrimitives::SetVertexColor( const Standard_Integer anIndex,
|
|
const Standard_Integer aColor)
|
|
{
|
|
if( !myPrimitiveArray ) return;
|
|
if( anIndex < 1 || anIndex > myMaxVertexs ) {
|
|
Standard_OutOfRange::Raise(" BAD VERTEX index");
|
|
}
|
|
Standard_Integer index = anIndex - 1;
|
|
if( myPrimitiveArray->vcolours ) {
|
|
#if defined (sparc) || defined (__sparc__) || defined (__sparc)
|
|
/*
|
|
Well known processor(x86) architectures that use the little-endian format.
|
|
Processors use big-endian format is SPARC. In this case use platform with
|
|
SPARC architecture(SUNOS). Byte order could have little-endian format.
|
|
*/
|
|
const char* p_ch = (const char*)&aColor;
|
|
myPrimitiveArray->vcolours[index] += p_ch[0];
|
|
myPrimitiveArray->vcolours[index] += p_ch[1] << 8 ;
|
|
myPrimitiveArray->vcolours[index] += p_ch[2] << 16;
|
|
myPrimitiveArray->vcolours[index] += p_ch[3] << 24;
|
|
#else
|
|
myPrimitiveArray->vcolours[index] = aColor;
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
void Graphic3d_ArrayOfPrimitives::SetVertexNormal(const Standard_Integer anIndex,
|
|
const gp_Dir& aNormal)
|
|
{
|
|
Standard_Real x,y,z;
|
|
aNormal.Coord(x,y,z);
|
|
SetVertexNormal(anIndex,x,y,z);
|
|
}
|
|
|
|
void Graphic3d_ArrayOfPrimitives::SetVertexTexel( const Standard_Integer anIndex,
|
|
const gp_Pnt2d& aTexel)
|
|
{
|
|
Standard_Real x,y;
|
|
aTexel.Coord(x,y);
|
|
SetVertexTexel(anIndex,x,y);
|
|
}
|
|
|
|
void Graphic3d_ArrayOfPrimitives::SetBoundColor(const Standard_Integer anIndex,
|
|
const Quantity_Color& aColor)
|
|
{
|
|
Standard_Real r,g,b;
|
|
aColor.Values(r,g,b,Quantity_TOC_RGB);
|
|
SetBoundColor(anIndex,r,g,b);
|
|
}
|
|
|
|
Standard_CString Graphic3d_ArrayOfPrimitives::StringType() const
|
|
{
|
|
TCollection_AsciiString name("UndefinedArray");
|
|
switch( myPrimitiveArray->type ) {
|
|
case TelPointsArrayType:
|
|
name = "ArrayOfPoints";
|
|
break;
|
|
case TelPolylinesArrayType:
|
|
name = "ArrayOfPolylines";
|
|
break;
|
|
case TelSegmentsArrayType:
|
|
name = "ArrayOfSegments";
|
|
break;
|
|
case TelPolygonsArrayType:
|
|
name = "ArrayOfPolygons";
|
|
break;
|
|
case TelTrianglesArrayType:
|
|
name = "ArrayOfTriangles";
|
|
break;
|
|
case TelQuadranglesArrayType:
|
|
name = "ArrayOfQuadrangles";
|
|
break;
|
|
case TelTriangleStripsArrayType:
|
|
name = "ArrayOfTriangleStrips";
|
|
break;
|
|
case TelQuadrangleStripsArrayType:
|
|
name = "ArrayOfQuadrangleStrips";
|
|
break;
|
|
case TelTriangleFansArrayType:
|
|
name = "ArrayOfTriangleFans";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return name.ToCString();
|
|
}
|
|
|
|
gp_Pnt Graphic3d_ArrayOfPrimitives::Vertice(const Standard_Integer aRank) const
|
|
{
|
|
Standard_Real x,y,z;
|
|
Vertice(aRank,x,y,z);
|
|
return gp_Pnt(x,y,z);
|
|
}
|
|
|
|
Quantity_Color Graphic3d_ArrayOfPrimitives::VertexColor(const Standard_Integer aRank) const
|
|
{
|
|
Standard_Real r,g,b;
|
|
VertexColor(aRank,r,g,b);
|
|
return Quantity_Color(r,g,b,Quantity_TOC_RGB);
|
|
}
|
|
|
|
gp_Dir Graphic3d_ArrayOfPrimitives::VertexNormal(const Standard_Integer aRank) const
|
|
{
|
|
Standard_Real x,y,z;
|
|
VertexNormal(aRank,x,y,z);
|
|
return gp_Dir(x,y,z);
|
|
}
|
|
|
|
gp_Pnt2d Graphic3d_ArrayOfPrimitives::VertexTexel(const Standard_Integer aRank) const
|
|
{
|
|
Standard_Real x,y;
|
|
VertexTexel(aRank,x,y);
|
|
return gp_Pnt2d(x,y);
|
|
}
|
|
|
|
Quantity_Color Graphic3d_ArrayOfPrimitives::BoundColor(const Standard_Integer aRank) const
|
|
{
|
|
Standard_Real r = 0.0, g = 0.0, b = 0.0;
|
|
BoundColor(aRank,r,g,b);
|
|
return Quantity_Color(r,g,b,Quantity_TOC_RGB);
|
|
}
|
|
|
|
Standard_Integer Graphic3d_ArrayOfPrimitives::ItemNumber() const
|
|
{
|
|
Standard_Integer number=-1;
|
|
if( myPrimitiveArray ) switch( myPrimitiveArray->type ) {
|
|
case TelPointsArrayType:
|
|
number = myPrimitiveArray->num_vertexs;
|
|
break;
|
|
case TelPolylinesArrayType:
|
|
case TelPolygonsArrayType:
|
|
if( myPrimitiveArray->num_bounds > 0 )
|
|
number = myPrimitiveArray->num_bounds;
|
|
else number = 1;
|
|
break;
|
|
case TelSegmentsArrayType:
|
|
if( myPrimitiveArray->num_edges > 0 )
|
|
number = myPrimitiveArray->num_edges/2;
|
|
else number = myPrimitiveArray->num_vertexs/2;
|
|
break;
|
|
case TelTrianglesArrayType:
|
|
if( myPrimitiveArray->num_edges > 0 )
|
|
number = myPrimitiveArray->num_edges/3;
|
|
else number = myPrimitiveArray->num_vertexs/3;
|
|
break;
|
|
case TelQuadranglesArrayType:
|
|
if( myPrimitiveArray->num_edges > 0 )
|
|
number = myPrimitiveArray->num_edges/4;
|
|
else number = myPrimitiveArray->num_vertexs/4;
|
|
break;
|
|
case TelTriangleStripsArrayType:
|
|
if( myPrimitiveArray->num_bounds > 0 )
|
|
number = myPrimitiveArray->num_vertexs-2*myPrimitiveArray->num_bounds;
|
|
else number = myPrimitiveArray->num_vertexs-2;
|
|
break;
|
|
case TelQuadrangleStripsArrayType:
|
|
if( myPrimitiveArray->num_bounds > 0 )
|
|
number = myPrimitiveArray->num_vertexs/2-myPrimitiveArray->num_bounds;
|
|
else number = myPrimitiveArray->num_vertexs/2-1;
|
|
break;
|
|
case TelTriangleFansArrayType:
|
|
if( myPrimitiveArray->num_bounds > 0 )
|
|
number = myPrimitiveArray->num_vertexs-2*myPrimitiveArray->num_bounds;
|
|
else number = myPrimitiveArray->num_vertexs-2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return number;
|
|
}
|
|
|
|
void Graphic3d_ArrayOfPrimitives::ComputeVNormals(const Standard_Integer from,
|
|
const Standard_Integer to)
|
|
{
|
|
Standard_Integer next = from+1;
|
|
Standard_Integer last = to+1;
|
|
gp_Pnt p1,p2,p3;
|
|
|
|
if( myMaxEdges > 0 ) {
|
|
p1 = Vertice(Edge(next++));
|
|
p2 = Vertice(Edge(next++));
|
|
} else {
|
|
p1 = Vertice(next++);
|
|
p2 = Vertice(next++);
|
|
}
|
|
|
|
gp_Vec vn;
|
|
|
|
while ( next <= last ) {
|
|
if( myMaxEdges > 0 ) {
|
|
p3 = Vertice(Edge(next));
|
|
} else {
|
|
p3 = Vertice(next);
|
|
}
|
|
gp_Vec v21(p2,p1);
|
|
gp_Vec v31(p3,p1);
|
|
vn = v21 ^ v31;
|
|
if( vn.SquareMagnitude() > 0. ) break;
|
|
next++;
|
|
}
|
|
|
|
if( next > last ) {
|
|
#if TRACE > 0
|
|
cout << " An item has a NULL computed facet normal" << endl;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
vn.Normalize();
|
|
if( myMaxEdges > 0 ) {
|
|
for( int i=from+1 ; i<=to+1 ; i++ ) {
|
|
SetVertexNormal(Edge(i),vn);
|
|
}
|
|
} else {
|
|
for( int i=from+1 ; i<=to+1 ; i++ ) {
|
|
SetVertexNormal(i,vn);
|
|
}
|
|
}
|
|
}
|
|
|
|
Standard_Boolean Graphic3d_ArrayOfPrimitives::IsValid()
|
|
{
|
|
if( !myPrimitiveArray ) return Standard_False;
|
|
|
|
Standard_Integer nvertexs = myPrimitiveArray->num_vertexs;
|
|
Standard_Integer nbounds = myPrimitiveArray->num_bounds;
|
|
Standard_Integer nedges = myPrimitiveArray->num_edges;
|
|
Standard_Integer i,n;
|
|
|
|
#if TRACE > 0
|
|
Standard_CString name = StringType();
|
|
cout << " !!! An " << name << " has " << ItemNumber() << " items" << endl;
|
|
#endif
|
|
|
|
switch( myPrimitiveArray->type ) {
|
|
case TelPointsArrayType:
|
|
if( nvertexs < 1 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
case TelPolylinesArrayType:
|
|
if( nedges > 0 && nedges < 2 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
if( nvertexs < 2 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
case TelSegmentsArrayType:
|
|
if( nvertexs < 2 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
case TelPolygonsArrayType:
|
|
if( nedges > 0 && nedges < 3 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
if( nvertexs < 3 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
case TelTrianglesArrayType:
|
|
if( nedges > 0 ) {
|
|
if( nedges < 3 || nedges % 3 != 0 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
|
|
#endif
|
|
if( nedges > 3 ) myPrimitiveArray->num_edges = 3 * (nedges / 3);
|
|
else return Standard_False;
|
|
}
|
|
} else if( nvertexs < 3 || nvertexs % 3 != 0 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
|
|
#endif
|
|
if( nvertexs > 3 ) myPrimitiveArray->num_vertexs = 3 * (nvertexs / 3);
|
|
else return Standard_False;
|
|
}
|
|
break;
|
|
case TelQuadranglesArrayType:
|
|
if( nedges > 0 ) {
|
|
if( nedges < 4 || nedges % 4 != 0 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
|
|
#endif
|
|
if( nedges > 4 ) myPrimitiveArray->num_edges = 4 * (nedges / 4);
|
|
else return Standard_False;
|
|
}
|
|
} else if( nvertexs < 4 || nvertexs % 4 != 0 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
|
|
#endif
|
|
if( nvertexs > 4 ) myPrimitiveArray->num_vertexs = 4 * (nvertexs / 4);
|
|
else return Standard_False;
|
|
}
|
|
break;
|
|
case TelTriangleFansArrayType:
|
|
case TelTriangleStripsArrayType:
|
|
if( nvertexs < 3 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
case TelQuadrangleStripsArrayType:
|
|
if( nvertexs < 4 ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
break;
|
|
default:
|
|
#if TRACE > 0
|
|
cout << " *** UNKNOWN Array of primitives type found" << endl;
|
|
#endif
|
|
return Standard_False;
|
|
}
|
|
|
|
// total number of edges(verticies) in bounds should be the same as variable
|
|
// of total number of defined edges(verticies); if no edges - only verticies
|
|
// could be in bounds.
|
|
if( nbounds > 0 ) {
|
|
for( i=n=0 ; i<nbounds ; i++ ) {
|
|
n += myPrimitiveArray->bounds[i];
|
|
}
|
|
if( nedges > 0 && n != nedges ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " has an incoherent number of edges " << nedges << endl;
|
|
#endif
|
|
if( nedges > n ) myPrimitiveArray->num_edges = n;
|
|
else return Standard_False;
|
|
} else if ( nedges == 0 && n != nvertexs ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " has an incoherent number of vertexs " << nvertexs << endl;
|
|
#endif
|
|
if( nvertexs > n ) myPrimitiveArray->num_vertexs = n;
|
|
else return Standard_False;
|
|
}
|
|
}
|
|
|
|
// check that edges (indexes to an array of verticies) are in range.
|
|
if( nedges > 0 ) {
|
|
for( i=0 ; i<nedges ; i++ ) {
|
|
if( myPrimitiveArray->edges[i] >= myPrimitiveArray->num_vertexs ) {
|
|
#if TRACE > 0
|
|
cout << " *** An " << name << " has a vertex index " << myPrimitiveArray->edges[i] << " greater than the number of defined vertexs " << myPrimitiveArray->num_vertexs << endl;
|
|
#endif
|
|
myPrimitiveArray->edges[i] = myPrimitiveArray->num_vertexs-1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|