3D viewer code cleaning round 1.
This commit is contained in:
parent
7cb2d19814
commit
d1fe4a0c98
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -93,11 +93,11 @@ void CBBOX2D::Reset()
|
|||
|
||||
void CBBOX2D::Union( const SFVEC2F &aPoint )
|
||||
{
|
||||
// get the minimun value between the added point and the existent bounding box
|
||||
// get the minimum value between the added point and the existent bounding box
|
||||
m_min.x = fminf( m_min.x, aPoint.x );
|
||||
m_min.y = fminf( m_min.y, aPoint.y );
|
||||
|
||||
// get the maximun value between the added point and the existent bounding box
|
||||
// get the maximum value between the added point and the existent bounding box
|
||||
m_max.x = fmaxf( m_max.x, aPoint.x );
|
||||
m_max.y = fmaxf( m_max.y, aPoint.y );
|
||||
}
|
||||
|
@ -105,12 +105,12 @@ void CBBOX2D::Union( const SFVEC2F &aPoint )
|
|||
|
||||
void CBBOX2D::Union( const CBBOX2D &aBBox )
|
||||
{
|
||||
// get the minimun value between the added bounding box and
|
||||
// get the minimum value between the added bounding box and
|
||||
// the existent bounding box
|
||||
m_min.x = fminf( m_min.x, aBBox.m_min.x );
|
||||
m_min.y = fminf( m_min.y, aBBox.m_min.y );
|
||||
|
||||
// get the maximun value between the added bounding box and
|
||||
// get the maximum value between the added bounding box and
|
||||
// the existent bounding box
|
||||
m_max.x = fmaxf( m_max.x, aBBox.m_max.x );
|
||||
m_max.y = fmaxf( m_max.y, aBBox.m_max.y );
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -34,8 +34,7 @@
|
|||
|
||||
|
||||
/**
|
||||
* CBBOX
|
||||
* manages a bounding box defined by two SFVEC2F min max points.
|
||||
* Manage a bounding box defined by two SFVEC2F min max points.
|
||||
*/
|
||||
struct CBBOX2D
|
||||
{
|
||||
|
@ -43,23 +42,22 @@ struct CBBOX2D
|
|||
public:
|
||||
|
||||
/**
|
||||
* Constructor CBBOX2D
|
||||
* Create with default values a bounding box (not inizialized)
|
||||
* Create with default values a bounding box (not initialized).
|
||||
*/
|
||||
CBBOX2D();
|
||||
|
||||
/**
|
||||
* Constructor CBBOX2D
|
||||
* Initialize a bounding box with a given point
|
||||
* @param aPbInit a point for the bounding box initialization
|
||||
* Initialize a bounding box with a given point.
|
||||
*
|
||||
* @param aPbInit a point for the bounding box initialization.
|
||||
*/
|
||||
explicit CBBOX2D( const SFVEC2F &aPbInit );
|
||||
|
||||
/**
|
||||
* Constructor CBBOX2D
|
||||
* Initialize a bounding box with a minimon and a maximun point
|
||||
* @param aPbMin the minimun point to initialize the bounding box
|
||||
* @param aPbMax the maximun point to initialize the bounding box
|
||||
* Initialize a bounding box with a minimum and a maximum point.
|
||||
*
|
||||
* @param aPbMin the minimum point to initialize the bounding box.
|
||||
* @param aPbMax the maximum point to initialize the bounding box.
|
||||
*/
|
||||
CBBOX2D( const SFVEC2F &aPbMin, const SFVEC2F &aPbMax );
|
||||
|
||||
|
@ -67,138 +65,130 @@ public:
|
|||
|
||||
|
||||
/**
|
||||
* Function Set
|
||||
* Set bounding box with new parameters
|
||||
* @param aPbMin the minimun point to initialize the bounding box
|
||||
* @param aPbMax the maximun point to initialize the bounding box
|
||||
* Set bounding box with new parameters.
|
||||
*
|
||||
* @param aPbMin the minimum point to initialize the bounding box.
|
||||
* @param aPbMax the maximum point to initialize the bounding box.
|
||||
*/
|
||||
void Set( const SFVEC2F &aPbMin, const SFVEC2F &aPbMax );
|
||||
|
||||
/**
|
||||
* Function Set
|
||||
* Set bounding box based on another bounding box
|
||||
* @param CBBOX2D a bounding box to initialize this one
|
||||
* Set bounding box based on another bounding box.
|
||||
*
|
||||
* @param CBBOX2D a bounding box to initialize this one.
|
||||
*/
|
||||
void Set( const CBBOX2D &aBBox );
|
||||
|
||||
/**
|
||||
* Function Union
|
||||
* recalculate the bounding box adding a point
|
||||
* Recalculate the bounding box adding a point.
|
||||
*
|
||||
* @param aPoint the point to be bounded
|
||||
*/
|
||||
void Union( const SFVEC2F &aPoint );
|
||||
|
||||
/**
|
||||
* Function Union
|
||||
* recalculate the bounding box adding other bounding box
|
||||
* @param aBBox the bounding box to be bounded
|
||||
* Recalculate the bounding box adding other bounding box.
|
||||
*
|
||||
* @param aBBox the bounding box to be bounded.
|
||||
*/
|
||||
void Union( const CBBOX2D &aBBox );
|
||||
|
||||
/**
|
||||
* Function Scale
|
||||
* scales a bounding box by its center
|
||||
* Scale a bounding box by its center.
|
||||
*
|
||||
* @param aScale scale factor to apply
|
||||
*/
|
||||
void Scale( float aScale );
|
||||
|
||||
/**
|
||||
* Function ScaleNextUp
|
||||
* scales a bounding box to the next float representation making it larger
|
||||
* Scale a bounding box to the next float representation making it larger.
|
||||
*/
|
||||
void ScaleNextUp();
|
||||
|
||||
/**
|
||||
* Function ScaleNextDown
|
||||
* scales a bounding box to the next float representation making it smaller
|
||||
* Scale a bounding box to the next float representation making it smaller.
|
||||
*/
|
||||
void ScaleNextDown();
|
||||
|
||||
/**
|
||||
* Function Intersects
|
||||
* test if a bounding box intersects this box
|
||||
* @param aBBox the bounding box to check if it inversects
|
||||
* Test if a bounding box intersects this box.
|
||||
*
|
||||
* @param aBBox the bounding box to check if it intersects.
|
||||
*/
|
||||
bool Intersects( const CBBOX2D &aBBox ) const;
|
||||
|
||||
/**
|
||||
* Function Intersects
|
||||
* test if a circle intersects this box
|
||||
* @param aBBox the bounding box to check if it intersects
|
||||
* Test if a circle intersects this box.
|
||||
*
|
||||
* @param aBBox the bounding box to check if it intersects.
|
||||
*/
|
||||
bool Intersects( const SFVEC2F &aCenter, float aRadiusSquared ) const;
|
||||
|
||||
/**
|
||||
* Function Inside
|
||||
* check is a point is inside this bounding box
|
||||
* @param aPoint point to test
|
||||
* Check is a point is inside this bounding box.
|
||||
*
|
||||
* @param aPoint point to test.
|
||||
*/
|
||||
bool Inside( const SFVEC2F &aPoint ) const;
|
||||
|
||||
/**
|
||||
* Function Area
|
||||
* calculate the area of a bounding box
|
||||
* @return float - area of this bounding box
|
||||
* Calculate the area of a bounding box.
|
||||
*
|
||||
* @return area of this bounding box.
|
||||
*/
|
||||
float Area() const;
|
||||
|
||||
/**
|
||||
* Function IsInitialized
|
||||
* check if this bounding box is already initialized
|
||||
* @return bool - return true if it was initialized, false if otherwise
|
||||
* Check if this bounding box is already initialized.
|
||||
*
|
||||
* @return True if it was initialized, otherwise false.
|
||||
*/
|
||||
bool IsInitialized() const;
|
||||
|
||||
/**
|
||||
* Function Reset
|
||||
* reset the bounding box to zero and de-initialized it
|
||||
* Reset the bounding box to zero and uninitialize it.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* Function GetCenter
|
||||
* return the center point of the bounding box
|
||||
* @return SFVEC2F - the position of the center of this bounding box
|
||||
* Return the center point of the bounding box.
|
||||
*
|
||||
* @return the position of the center of this bounding box.
|
||||
*/
|
||||
SFVEC2F GetCenter() const;
|
||||
|
||||
/**
|
||||
* Function GetExtent
|
||||
* @return SFVEC2F - max-min
|
||||
*/
|
||||
SFVEC2F GetExtent() const;
|
||||
|
||||
/**
|
||||
* Function Min
|
||||
* return the minimun vertex pointer
|
||||
* @return SFVEC2F - the minimun vertice position
|
||||
* Return the minimum vertex point.
|
||||
*
|
||||
* @return the minimum vertex position.
|
||||
*/
|
||||
const SFVEC2F &Min() const { return m_min; }
|
||||
|
||||
/**
|
||||
* Function Max
|
||||
* return the maximum vertex pointer
|
||||
* @return SFVEC2F - the maximun vertice position
|
||||
* Return the maximum vertex point.
|
||||
* @return the maximum vertex position.
|
||||
*/
|
||||
const SFVEC2F &Max() const { return m_max; }
|
||||
|
||||
|
||||
/**
|
||||
* Function MaxDimension
|
||||
* @return the index of the max dimention (0=x, 1=y)
|
||||
* @return the index of the max dimension (0=x, 1=y)
|
||||
*/
|
||||
unsigned int MaxDimension() const;
|
||||
|
||||
/**
|
||||
* Function Perimeter
|
||||
* @return the surface are of the box
|
||||
* @return the surface area of the box
|
||||
*/
|
||||
float Perimeter() const;
|
||||
|
||||
/**
|
||||
* Function Intersect
|
||||
* @param aRay = ray to intersect the box
|
||||
* @param t = distance point of the ray of the intersection (if true)
|
||||
* @param aRay ray to intersect the box
|
||||
* @param t distance point of the ray of the intersection (if true)
|
||||
* @return true if the ray hits the box
|
||||
*/
|
||||
bool Intersect( const RAY2D &aRay, float *t ) const;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -35,24 +35,23 @@
|
|||
class CFILLEDCIRCLE2D : public COBJECT2D
|
||||
{
|
||||
public:
|
||||
CFILLEDCIRCLE2D( const SFVEC2F &aCenter, float aRadius, const BOARD_ITEM &aBoardItem );
|
||||
|
||||
float GetRadius() const { return m_radius; }
|
||||
const SFVEC2F &GetCenter() const { return m_center; }
|
||||
float GetRadiusSquared() const { return m_radius_squared; }
|
||||
|
||||
private:
|
||||
SFVEC2F m_center;
|
||||
float m_radius;
|
||||
float m_radius_squared;
|
||||
|
||||
public:
|
||||
CFILLEDCIRCLE2D( const SFVEC2F &aCenter, float aRadius, const BOARD_ITEM &aBoardItem );
|
||||
|
||||
// Imported from COBJECT2D
|
||||
bool Overlaps( const CBBOX2D &aBBox ) const override;
|
||||
bool Intersects( const CBBOX2D &aBBox ) const override;
|
||||
bool Intersect( const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut ) const override;
|
||||
INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const override;
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
|
||||
private:
|
||||
SFVEC2F m_center;
|
||||
float m_radius;
|
||||
float m_radius_squared;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -31,13 +31,15 @@
|
|||
#include "3d_fastmath.h"
|
||||
#include <wx/debug.h>
|
||||
|
||||
|
||||
CITEMLAYERCSG2D::CITEMLAYERCSG2D( const COBJECT2D* aObjectA,
|
||||
std::vector<const COBJECT2D*>* aObjectB, const COBJECT2D* aObjectC,
|
||||
const BOARD_ITEM& aBoardItem )
|
||||
: COBJECT2D( OBJECT2D_TYPE::CSG, aBoardItem ),
|
||||
m_objectA( aObjectA ),
|
||||
m_objectB( aObjectB ),
|
||||
m_objectC( aObjectC )
|
||||
std::vector<const COBJECT2D*>* aObjectB,
|
||||
const COBJECT2D* aObjectC,
|
||||
const BOARD_ITEM& aBoardItem ) :
|
||||
COBJECT2D( OBJECT2D_TYPE::CSG, aBoardItem ),
|
||||
m_objectA( aObjectA ),
|
||||
m_objectB( aObjectB ),
|
||||
m_objectC( aObjectC )
|
||||
{
|
||||
wxASSERT( aObjectA );
|
||||
|
||||
|
@ -52,8 +54,7 @@ CITEMLAYERCSG2D::CITEMLAYERCSG2D( const COBJECT2D* aObjectA,
|
|||
|
||||
CITEMLAYERCSG2D::~CITEMLAYERCSG2D()
|
||||
{
|
||||
if( ((void*)m_objectB != CSGITEM_EMPTY) &&
|
||||
((void*)m_objectB != CSGITEM_FULL) )
|
||||
if( ( (void*) m_objectB != CSGITEM_EMPTY ) && ( (void*) m_objectB != CSGITEM_FULL ) )
|
||||
{
|
||||
delete m_objectB;
|
||||
m_objectB = NULL;
|
||||
|
@ -61,31 +62,30 @@ CITEMLAYERCSG2D::~CITEMLAYERCSG2D()
|
|||
}
|
||||
|
||||
|
||||
bool CITEMLAYERCSG2D::Intersects( const CBBOX2D &aBBox ) const
|
||||
bool CITEMLAYERCSG2D::Intersects( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
return m_bbox.Intersects( aBBox );
|
||||
// !TODO: improove this implementation
|
||||
// !TODO: improve this implementation
|
||||
//return false;
|
||||
}
|
||||
|
||||
|
||||
bool CITEMLAYERCSG2D::Overlaps( const CBBOX2D &aBBox ) const
|
||||
bool CITEMLAYERCSG2D::Overlaps( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
// NOT IMPLEMENTED
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Based on ideas and implementation by Nick Chapman
|
||||
// http://homepages.paradise.net.nz/nickamy/raytracer/raytracer.htm
|
||||
bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
|
||||
float *aOutT,
|
||||
SFVEC2F *aNormalOut ) const
|
||||
bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D& aSegRay, float* aOutT, SFVEC2F* aNormalOut ) const
|
||||
{
|
||||
if( m_objectA->GetObjectType() == OBJECT2D_TYPE::DUMMYBLOCK )
|
||||
return false;
|
||||
|
||||
SFVEC2F currentRayPos = aSegRay.m_Start;
|
||||
SFVEC2F currentNormal;
|
||||
SFVEC2F currentRayPos = aSegRay.m_Start;
|
||||
SFVEC2F currentNormal;
|
||||
RAYSEG2D currentRay = aSegRay;
|
||||
|
||||
if( !m_objectA->IsPointInside( aSegRay.m_Start ) )
|
||||
|
@ -102,7 +102,6 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
|
||||
//wxASSERT( (currentRayDist >= 0.0f) && (currentRayDist <= 1.0f) );
|
||||
|
||||
|
||||
// move through the union of subtracted regions
|
||||
if( m_objectB )
|
||||
{
|
||||
|
@ -113,15 +112,14 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
//check against all subbed objects
|
||||
for( unsigned int i = 0; i < m_objectB->size(); ++i )
|
||||
{
|
||||
if( ( (const COBJECT2D *)( *m_objectB)[i] )->IsPointInside( currentRayPos ) )
|
||||
if( ( (const COBJECT2D*) ( *m_objectB )[i] )->IsPointInside( currentRayPos ) )
|
||||
{
|
||||
// ray point is inside a subtracted region, so move it to the end of the
|
||||
// subtracted region
|
||||
float hitDist;
|
||||
float hitDist;
|
||||
SFVEC2F tmpNormal;
|
||||
if( !( (const COBJECT2D *)( *m_objectB)[i] )->Intersect( currentRay,
|
||||
&hitDist,
|
||||
&tmpNormal ) )
|
||||
if( !( (const COBJECT2D*) ( *m_objectB )[i] )
|
||||
->Intersect( currentRay, &hitDist, &tmpNormal ) )
|
||||
return false; // ray hit main object but did not leave subtracted volume
|
||||
|
||||
wxASSERT( hitDist <= 1.0f );
|
||||
|
@ -130,7 +128,8 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
{
|
||||
wasCrossedSubVol = true;
|
||||
|
||||
currentRayPos = currentRay.atNormalized( glm::min( hitDist + 0.0001f, 1.0f ) );
|
||||
currentRayPos =
|
||||
currentRay.atNormalized( glm::min( hitDist + 0.0001f, 1.0f ) );
|
||||
|
||||
currentRay = RAYSEG2D( currentRayPos, aSegRay.m_End );
|
||||
|
||||
|
@ -148,13 +147,15 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
*aNormalOut = currentNormal;
|
||||
|
||||
if( aOutT )
|
||||
*aOutT = glm::min( glm::max( glm::length( currentRayPos - aSegRay.m_Start ) / aSegRay.m_Length, 0.0f ), 1.0f );
|
||||
*aOutT = glm::min(
|
||||
glm::max( glm::length( currentRayPos - aSegRay.m_Start ) / aSegRay.m_Length, 0.0f ),
|
||||
1.0f );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
INTERSECTION_RESULT CITEMLAYERCSG2D::IsBBoxInside( const CBBOX2D &aBBox ) const
|
||||
INTERSECTION_RESULT CITEMLAYERCSG2D::IsBBoxInside( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
|
||||
// !TODO:
|
||||
|
@ -163,19 +164,20 @@ INTERSECTION_RESULT CITEMLAYERCSG2D::IsBBoxInside( const CBBOX2D &aBBox ) const
|
|||
}
|
||||
|
||||
|
||||
bool CITEMLAYERCSG2D::IsPointInside( const SFVEC2F &aPoint ) const
|
||||
bool CITEMLAYERCSG2D::IsPointInside( const SFVEC2F& aPoint ) const
|
||||
{
|
||||
// Perform the operation (A - B) /\ C
|
||||
|
||||
if( m_objectA->IsPointInside( aPoint ) )
|
||||
{
|
||||
|
||||
if( m_objectB != CSGITEM_EMPTY)
|
||||
for( unsigned int i = 0; i< m_objectB->size(); i++ )
|
||||
if( m_objectB != CSGITEM_EMPTY )
|
||||
{
|
||||
for( unsigned int i = 0; i < m_objectB->size(); i++ )
|
||||
{
|
||||
if( (*m_objectB)[i]->IsPointInside( aPoint ) )
|
||||
if( ( *m_objectB )[i]->IsPointInside( aPoint ) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// !TODO: not yet implemented
|
||||
//if( m_objectC && m_objectC != CSGITEM_FULL )
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -33,9 +33,13 @@
|
|||
#include "cobject2d.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
#define CSGITEM_EMPTY 0
|
||||
#define CSGITEM_FULL (COBJECT2D *)((size_t)(-1))
|
||||
|
||||
/**
|
||||
* This class is used to make constructive solig geometry for items
|
||||
* objects on layers.
|
||||
* Make constructive solid geometry for items objects on layers.
|
||||
*
|
||||
* The operation is in the form (A - B) /\ C
|
||||
* For almost all of the layers it translate something like:
|
||||
* A (a via, a track, pad, polygon), B (a via hole, a THT hole, .. ),
|
||||
|
@ -71,17 +75,8 @@
|
|||
* Layers.Paste = P - 0 /\ BODY
|
||||
* Layers.Silk = S - 0 /\ BODY
|
||||
*/
|
||||
|
||||
#define CSGITEM_EMPTY 0
|
||||
#define CSGITEM_FULL (COBJECT2D *)((size_t)(-1))
|
||||
|
||||
class CITEMLAYERCSG2D : public COBJECT2D
|
||||
{
|
||||
private:
|
||||
const COBJECT2D *m_objectA;
|
||||
std::vector<const COBJECT2D *> *m_objectB;
|
||||
const COBJECT2D *m_objectC;
|
||||
|
||||
public:
|
||||
CITEMLAYERCSG2D( const COBJECT2D *aObjectA,
|
||||
std::vector<const COBJECT2D *> *aObjectB,
|
||||
|
@ -96,7 +91,11 @@ public:
|
|||
bool Intersect( const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut ) const override;
|
||||
INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const override;
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
|
||||
private:
|
||||
const COBJECT2D *m_objectA;
|
||||
std::vector<const COBJECT2D *> *m_objectB;
|
||||
const COBJECT2D *m_objectC;
|
||||
};
|
||||
|
||||
|
||||
#endif // _CITEMLAYERCSG2D_H_
|
||||
|
|
|
@ -67,6 +67,6 @@ void COBJECT2D_STATS::PrintStats()
|
|||
for( auto& objectType : objectTypeNames )
|
||||
{
|
||||
wxLogDebug( " %20s %u\n", objectType.second,
|
||||
m_counter[static_cast<int>( objectType.first )] );
|
||||
m_counter[static_cast<int>( objectType.first )] );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,57 +61,44 @@ enum class OBJECT2D_TYPE
|
|||
|
||||
class COBJECT2D
|
||||
{
|
||||
protected:
|
||||
CBBOX2D m_bbox;
|
||||
SFVEC2F m_centroid;
|
||||
OBJECT2D_TYPE m_obj_type;
|
||||
|
||||
const BOARD_ITEM &m_boardItem;
|
||||
public:
|
||||
|
||||
COBJECT2D( OBJECT2D_TYPE aObjType, const BOARD_ITEM &aBoardItem );
|
||||
virtual ~COBJECT2D() {}
|
||||
|
||||
const BOARD_ITEM &GetBoardItem() const { return m_boardItem; }
|
||||
|
||||
/** Function Overlaps
|
||||
* @brief Test if the box overlaps the object
|
||||
/**
|
||||
* Test if the box overlaps the object.
|
||||
*
|
||||
* Conformance
|
||||
* The function overlaps implements function Overlaps from the OGC
|
||||
* Simple Feature Specification.
|
||||
* http://www.opengeospatial.org/standards/sfa
|
||||
* Implements the Overlaps function from the OGC Simple Feature Specification at
|
||||
* http://www.opengeospatial.org/standards/sfa.
|
||||
* a.Overlaps(b) ⇔ ( dim(I(a)) = dim(I(b)) = dim(I(a) ∩ I(b))) ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b)
|
||||
* It means that the result dimension of an overlap is the same dimentions
|
||||
* It means that the result dimension of an overlap is the same dimensions
|
||||
* of the bounding box (so the overlap cannot be a point or a line) and one
|
||||
* of the boxes cannot full contain the other box.
|
||||
*
|
||||
* @param aBBox - The bounding box to test
|
||||
* @return true if the BBox intersects the object or is inside it
|
||||
*/
|
||||
virtual bool Overlaps( const CBBOX2D &aBBox ) const = 0;
|
||||
|
||||
/** Function Intersects
|
||||
* @brief Intersects - a.Intersects(b) ⇔ !a.Disjoint(b) ⇔ !(a ∩ b = ∅)
|
||||
* It intersects if the result intersection is not null
|
||||
* @param aBBox
|
||||
* @return
|
||||
/**
|
||||
* a.Intersects(b) ⇔ !a.Disjoint(b) ⇔ !(a ∩ b = ∅)
|
||||
*/
|
||||
virtual bool Intersects( const CBBOX2D &aBBox ) const = 0;
|
||||
|
||||
/** Function Intersect
|
||||
* @brief Intersect
|
||||
* @param aSegRay
|
||||
/**
|
||||
* @param aOutT a value between 0.0 and 1.0 in relation to the time of the
|
||||
* hit of the segment
|
||||
* @param aNormalOut
|
||||
* @return
|
||||
*/
|
||||
virtual bool Intersect( const RAYSEG2D &aSegRay,
|
||||
float *aOutT,
|
||||
SFVEC2F *aNormalOut ) const = 0;
|
||||
|
||||
/**
|
||||
* Function IsBBoxInside
|
||||
* @brief Tests if the bounding is out, intersects or is complety inside
|
||||
* Test this object if it's completely outside, intersects, or is completely inside \a aBBox.
|
||||
*
|
||||
* @return INTERSECTION_RESULT
|
||||
*/
|
||||
virtual INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const = 0;
|
||||
|
@ -123,12 +110,17 @@ public:
|
|||
const SFVEC2F &GetCentroid() const { return m_centroid; }
|
||||
|
||||
OBJECT2D_TYPE GetObjectType() const { return m_obj_type; }
|
||||
|
||||
protected:
|
||||
CBBOX2D m_bbox;
|
||||
SFVEC2F m_centroid;
|
||||
OBJECT2D_TYPE m_obj_type;
|
||||
|
||||
const BOARD_ITEM &m_boardItem;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Implements a class for object statistics
|
||||
/// using Singleton pattern
|
||||
class COBJECT2D_STATS
|
||||
{
|
||||
public:
|
||||
|
@ -163,7 +155,6 @@ private:
|
|||
const COBJECT2D_STATS &operator=( const COBJECT2D_STATS &old );
|
||||
~COBJECT2D_STATS(){}
|
||||
|
||||
private:
|
||||
unsigned int m_counter[static_cast<int>( OBJECT2D_TYPE::MAX )];
|
||||
|
||||
static COBJECT2D_STATS *s_instance;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -34,34 +34,30 @@
|
|||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
// CPOLYGONBLOCK2D
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool polygon_IsPointInside( const SEGMENTS &aSegments, const SFVEC2F &aPoint )
|
||||
static bool polygon_IsPointInside( const SEGMENTS& aSegments, const SFVEC2F& aPoint )
|
||||
{
|
||||
wxASSERT( aSegments.size() >= 3 );
|
||||
|
||||
unsigned int i;
|
||||
unsigned int j = aSegments.size() - 1;
|
||||
bool oddNodes = false;
|
||||
unsigned int j = aSegments.size() - 1;
|
||||
bool oddNodes = false;
|
||||
|
||||
for( i = 0; i < aSegments.size(); j = i++ )
|
||||
{
|
||||
const float polyJY = aSegments[j].m_Start.y;
|
||||
const float polyIY = aSegments[i].m_Start.y;
|
||||
|
||||
if( ((polyIY <= aPoint.y) && (polyJY >= aPoint.y)) ||
|
||||
((polyJY <= aPoint.y) && (polyIY >= aPoint.y))
|
||||
)
|
||||
if( ( ( polyIY <= aPoint.y ) && ( polyJY >= aPoint.y ) )
|
||||
|| ( ( polyJY <= aPoint.y ) && ( polyIY >= aPoint.y ) ) )
|
||||
{
|
||||
const float polyJX = aSegments[j].m_Start.x;
|
||||
const float polyIX = aSegments[i].m_Start.x;
|
||||
|
||||
if( (polyIX <= aPoint.x) || (polyJX <= aPoint.x) )
|
||||
oddNodes ^= ( ( polyIX +
|
||||
( ( aPoint.y - polyIY ) *
|
||||
aSegments[i].m_inv_JY_minus_IY ) *
|
||||
aSegments[i].m_JX_minus_IX ) < aPoint.x );
|
||||
if( ( polyIX <= aPoint.x ) || ( polyJX <= aPoint.x ) )
|
||||
oddNodes ^= ( ( polyIX + ( ( aPoint.y - polyIY ) * aSegments[i].m_inv_JY_minus_IY )
|
||||
* aSegments[i].m_JX_minus_IX )
|
||||
< aPoint.x );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,29 +83,28 @@ CPOLYGONBLOCK2D::CPOLYGONBLOCK2D( const SEGMENTS_WIDTH_NORMALS& aOpenSegmentList
|
|||
for( unsigned int i = 0; i < m_outers_and_holes.m_Outers.size(); i++ )
|
||||
{
|
||||
for( unsigned int j = 0; j < m_outers_and_holes.m_Outers[i].size(); j++ )
|
||||
m_bbox.Union( ((SEGMENTS)m_outers_and_holes.m_Outers[i])[j].m_Start );
|
||||
m_bbox.Union( ( (SEGMENTS) m_outers_and_holes.m_Outers[i] )[j].m_Start );
|
||||
}
|
||||
|
||||
m_bbox.ScaleNextUp();
|
||||
m_centroid = m_bbox.GetCenter();
|
||||
|
||||
// Some checks
|
||||
wxASSERT( m_open_segments.size() == aOpenSegmentList.size() );
|
||||
wxASSERT( m_open_segments.size() == aOpenSegmentList.size() );
|
||||
wxASSERT( m_open_segments.size() > 0 );
|
||||
|
||||
wxASSERT( m_outers_and_holes.m_Outers.size() > 0 );
|
||||
wxASSERT( m_outers_and_holes.m_Outers.size() == aOuter_and_holes.m_Outers.size() );
|
||||
wxASSERT( m_outers_and_holes.m_Holes.size() == aOuter_and_holes.m_Holes.size() );
|
||||
wxASSERT( m_outers_and_holes.m_Holes.size() == aOuter_and_holes.m_Holes.size() );
|
||||
|
||||
wxASSERT( m_outers_and_holes.m_Outers[0].size() >= 3 );
|
||||
wxASSERT( m_outers_and_holes.m_Outers[0].size() ==
|
||||
aOuter_and_holes.m_Outers[0].size() );
|
||||
wxASSERT( m_outers_and_holes.m_Outers[0].size() == aOuter_and_holes.m_Outers[0].size() );
|
||||
|
||||
wxASSERT( m_bbox.IsInitialized() );
|
||||
}
|
||||
|
||||
|
||||
bool CPOLYGONBLOCK2D::Intersects( const CBBOX2D &aBBox ) const
|
||||
bool CPOLYGONBLOCK2D::Intersects( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
return m_bbox.Intersects( aBBox );
|
||||
|
||||
|
@ -119,67 +114,64 @@ bool CPOLYGONBLOCK2D::Intersects( const CBBOX2D &aBBox ) const
|
|||
}
|
||||
|
||||
|
||||
bool CPOLYGONBLOCK2D::Overlaps( const CBBOX2D &aBBox ) const
|
||||
bool CPOLYGONBLOCK2D::Overlaps( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
// NOT IMPLEMENTED
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CPOLYGONBLOCK2D::Intersect( const RAYSEG2D &aSegRay,
|
||||
float *aOutT,
|
||||
SFVEC2F *aNormalOut ) const
|
||||
bool CPOLYGONBLOCK2D::Intersect( const RAYSEG2D& aSegRay, float* aOutT, SFVEC2F* aNormalOut ) const
|
||||
{
|
||||
int hitIndex = -1;
|
||||
float hitU = 0.0f;
|
||||
float tMin = 0.0f;
|
||||
int hitIndex = -1;
|
||||
float hitU = 0.0f;
|
||||
float tMin = 0.0f;
|
||||
|
||||
for( unsigned int i = 0; i < m_open_segments.size(); i++ )
|
||||
{
|
||||
const SFVEC2F &s = m_open_segments[i].m_Precalc_slope;
|
||||
const SFVEC2F &q = m_open_segments[i].m_Start;
|
||||
const SFVEC2F& s = m_open_segments[i].m_Precalc_slope;
|
||||
const SFVEC2F& q = m_open_segments[i].m_Start;
|
||||
|
||||
float rxs = aSegRay.m_End_minus_start.x * s.y -
|
||||
aSegRay.m_End_minus_start.y * s.x;
|
||||
float rxs = aSegRay.m_End_minus_start.x * s.y - aSegRay.m_End_minus_start.y * s.x;
|
||||
|
||||
if( fabs(rxs) > FLT_EPSILON )
|
||||
if( fabs( rxs ) > FLT_EPSILON )
|
||||
{
|
||||
const float inv_rxs = 1.0f / rxs;
|
||||
|
||||
const SFVEC2F pq = q - aSegRay.m_Start;
|
||||
|
||||
const float t = (pq.x * s.y - pq.y * s.x) * inv_rxs;
|
||||
const float t = ( pq.x * s.y - pq.y * s.x ) * inv_rxs;
|
||||
|
||||
if( (t < 0.0f) || (t > 1.0f) )
|
||||
if( ( t < 0.0f ) || ( t > 1.0f ) )
|
||||
continue;
|
||||
|
||||
const float u = ( pq.x * aSegRay.m_End_minus_start.y -
|
||||
pq.y * aSegRay.m_End_minus_start.x ) * inv_rxs;
|
||||
const float u =
|
||||
( pq.x * aSegRay.m_End_minus_start.y - pq.y * aSegRay.m_End_minus_start.x )
|
||||
* inv_rxs;
|
||||
|
||||
if( (u < 0.0f) || (u > 1.0f) )
|
||||
if( ( u < 0.0f ) || ( u > 1.0f ) )
|
||||
continue;
|
||||
|
||||
if( ( hitIndex == -1 ) || ( t <= tMin ) )
|
||||
{
|
||||
tMin = t;
|
||||
tMin = t;
|
||||
hitIndex = i;
|
||||
hitU = u;
|
||||
hitU = u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( hitIndex >= 0 )
|
||||
{
|
||||
wxASSERT( (tMin >= 0.0f) && (tMin <= 1.0f) );
|
||||
wxASSERT( ( tMin >= 0.0f ) && ( tMin <= 1.0f ) );
|
||||
|
||||
if( aOutT )
|
||||
*aOutT = tMin;
|
||||
|
||||
if( aNormalOut )
|
||||
*aNormalOut = glm::normalize(
|
||||
m_open_segments[hitIndex].m_Normals.m_Start * hitU +
|
||||
m_open_segments[hitIndex].m_Normals.m_End *
|
||||
(1.0f - hitU) );
|
||||
*aNormalOut = glm::normalize( m_open_segments[hitIndex].m_Normals.m_Start * hitU +
|
||||
m_open_segments[hitIndex].m_Normals.m_End *
|
||||
( 1.0f - hitU ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -188,14 +180,14 @@ bool CPOLYGONBLOCK2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
}
|
||||
|
||||
|
||||
INTERSECTION_RESULT CPOLYGONBLOCK2D::IsBBoxInside( const CBBOX2D &aBBox ) const
|
||||
INTERSECTION_RESULT CPOLYGONBLOCK2D::IsBBoxInside( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
|
||||
return INTERSECTION_RESULT::MISSES;
|
||||
}
|
||||
|
||||
|
||||
bool CPOLYGONBLOCK2D::IsPointInside( const SFVEC2F &aPoint ) const
|
||||
bool CPOLYGONBLOCK2D::IsPointInside( const SFVEC2F& aPoint ) const
|
||||
{
|
||||
// NOTE: we could add here a test for the bounding box, but because in the
|
||||
// 3d object it already checked for a 3d bbox.
|
||||
|
@ -219,11 +211,8 @@ bool CPOLYGONBLOCK2D::IsPointInside( const SFVEC2F &aPoint ) const
|
|||
}
|
||||
|
||||
|
||||
// CDUMMYBLOCK2D
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CDUMMYBLOCK2D::CDUMMYBLOCK2D(
|
||||
const SFVEC2F& aPbMin, const SFVEC2F& aPbMax, const BOARD_ITEM& aBoardItem )
|
||||
CDUMMYBLOCK2D::CDUMMYBLOCK2D( const SFVEC2F& aPbMin, const SFVEC2F& aPbMax,
|
||||
const BOARD_ITEM& aBoardItem )
|
||||
: COBJECT2D( OBJECT2D_TYPE::DUMMYBLOCK, aBoardItem )
|
||||
{
|
||||
m_bbox.Set( aPbMin, aPbMax );
|
||||
|
@ -241,22 +230,20 @@ CDUMMYBLOCK2D::CDUMMYBLOCK2D( const CBBOX2D& aBBox, const BOARD_ITEM& aBoardItem
|
|||
}
|
||||
|
||||
|
||||
bool CDUMMYBLOCK2D::Intersects( const CBBOX2D &aBBox ) const
|
||||
bool CDUMMYBLOCK2D::Intersects( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
return m_bbox.Intersects( aBBox );
|
||||
}
|
||||
|
||||
|
||||
bool CDUMMYBLOCK2D::Overlaps( const CBBOX2D &aBBox ) const
|
||||
bool CDUMMYBLOCK2D::Overlaps( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
// Not implemented
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CDUMMYBLOCK2D::Intersect( const RAYSEG2D &aSegRay,
|
||||
float *aOutT,
|
||||
SFVEC2F *aNormalOut ) const
|
||||
bool CDUMMYBLOCK2D::Intersect( const RAYSEG2D& aSegRay, float* aOutT, SFVEC2F* aNormalOut ) const
|
||||
{
|
||||
// The dummy block will be never intersected because it have no edges,
|
||||
// only it have a plan surface of the size of the bounding box
|
||||
|
@ -264,14 +251,14 @@ bool CDUMMYBLOCK2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
}
|
||||
|
||||
|
||||
INTERSECTION_RESULT CDUMMYBLOCK2D::IsBBoxInside( const CBBOX2D &aBBox ) const
|
||||
INTERSECTION_RESULT CDUMMYBLOCK2D::IsBBoxInside( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
//!TODO:
|
||||
return INTERSECTION_RESULT::MISSES;
|
||||
}
|
||||
|
||||
|
||||
bool CDUMMYBLOCK2D::IsPointInside( const SFVEC2F &aPoint ) const
|
||||
bool CDUMMYBLOCK2D::IsPointInside( const SFVEC2F& aPoint ) const
|
||||
{
|
||||
// The dummy is filled in all his bounding box, so if it hit the bbox
|
||||
// it will hit this dummy
|
||||
|
@ -282,17 +269,13 @@ bool CDUMMYBLOCK2D::IsPointInside( const SFVEC2F &aPoint ) const
|
|||
}
|
||||
|
||||
|
||||
// Polygon process and conversion
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef std::vector<SFVEC2F> KF_POINTS;
|
||||
|
||||
#define MAX_NR_DIVISIONS 96
|
||||
|
||||
|
||||
static bool intersect( const SEGMENT_WITH_NORMALS &aSeg,
|
||||
const SFVEC2F &aStart,
|
||||
const SFVEC2F &aEnd )
|
||||
static bool intersect( const SEGMENT_WITH_NORMALS& aSeg, const SFVEC2F& aStart,
|
||||
const SFVEC2F& aEnd )
|
||||
{
|
||||
const SFVEC2F r = aEnd - aStart;
|
||||
const SFVEC2F s = aSeg.m_Precalc_slope;
|
||||
|
@ -300,20 +283,20 @@ static bool intersect( const SEGMENT_WITH_NORMALS &aSeg,
|
|||
|
||||
const float rxs = r.x * s.y - r.y * s.x;
|
||||
|
||||
if( fabs(rxs) > glm::epsilon<float>() )
|
||||
if( fabs( rxs ) > glm::epsilon<float>() )
|
||||
{
|
||||
const float inv_rxs = 1.0f / rxs;
|
||||
|
||||
const SFVEC2F pq = q - aStart;
|
||||
|
||||
const float t = (pq.x * s.y - pq.y * s.x) * inv_rxs;
|
||||
const float t = ( pq.x * s.y - pq.y * s.x ) * inv_rxs;
|
||||
|
||||
if( (t < 0.0f) || (t > 1.0f) )
|
||||
if( ( t < 0.0f ) || ( t > 1.0f ) )
|
||||
return false;
|
||||
|
||||
const float u = (pq.x * r.y - pq.y * r.x) * inv_rxs;
|
||||
const float u = ( pq.x * r.y - pq.y * r.x ) * inv_rxs;
|
||||
|
||||
if( (u < 0.0f) || (u > 1.0f) )
|
||||
if( ( u < 0.0f ) || ( u > 1.0f ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -323,11 +306,10 @@ static bool intersect( const SEGMENT_WITH_NORMALS &aSeg,
|
|||
}
|
||||
|
||||
|
||||
static void extractPathsFrom( const SEGMENTS_WIDTH_NORMALS &aSegList,
|
||||
const CBBOX2D &aBBox,
|
||||
SEGMENTS_WIDTH_NORMALS &aOutSegThatIntersect )
|
||||
static void extractPathsFrom( const SEGMENTS_WIDTH_NORMALS& aSegList, const CBBOX2D& aBBox,
|
||||
SEGMENTS_WIDTH_NORMALS& aOutSegThatIntersect )
|
||||
{
|
||||
wxASSERT( aSegList.size () >= 3 );
|
||||
wxASSERT( aSegList.size() >= 3 );
|
||||
|
||||
unsigned int i;
|
||||
unsigned int j = aSegList.size() - 1;
|
||||
|
@ -341,8 +323,7 @@ static void extractPathsFrom( const SEGMENTS_WIDTH_NORMALS &aSegList,
|
|||
|
||||
for( i = 0; i < aSegList.size(); j = i++ )
|
||||
{
|
||||
if( aBBox.Inside( aSegList[i].m_Start ) ||
|
||||
aBBox.Inside( aSegList[j].m_Start ) )
|
||||
if( aBBox.Inside( aSegList[i].m_Start ) || aBBox.Inside( aSegList[j].m_Start ) )
|
||||
{
|
||||
// if the segment points are inside the bounding box then this
|
||||
// segment is touching the bbox.
|
||||
|
@ -353,18 +334,15 @@ static void extractPathsFrom( const SEGMENTS_WIDTH_NORMALS &aSegList,
|
|||
// Check if a segment intersects the bounding box
|
||||
|
||||
// Make a bounding box based on the segments start and end
|
||||
CBBOX2D segmentBBox( aSegList[i].m_Start,
|
||||
aSegList[j].m_Start );
|
||||
CBBOX2D segmentBBox( aSegList[i].m_Start, aSegList[j].m_Start );
|
||||
|
||||
if( aBBox.Intersects( segmentBBox ) )
|
||||
{
|
||||
|
||||
const SEGMENT_WITH_NORMALS &seg = aSegList[i];
|
||||
const SEGMENT_WITH_NORMALS& seg = aSegList[i];
|
||||
|
||||
if( intersect( seg, p1, p2 ) ||
|
||||
intersect( seg, p2, p3 ) ||
|
||||
intersect( seg, p3, p4 ) ||
|
||||
intersect( seg, p4, p1 ) )
|
||||
if( intersect( seg, p1, p2 ) || intersect( seg, p2, p3 ) || intersect( seg, p3, p4 )
|
||||
|| intersect( seg, p4, p1 ) )
|
||||
{
|
||||
aOutSegThatIntersect.push_back( seg );
|
||||
}
|
||||
|
@ -374,45 +352,38 @@ static void extractPathsFrom( const SEGMENTS_WIDTH_NORMALS &aSegList,
|
|||
}
|
||||
|
||||
|
||||
static void polygon_Convert( const SHAPE_LINE_CHAIN &aPath,
|
||||
SEGMENTS &aOutSegment,
|
||||
static void polygon_Convert( const SHAPE_LINE_CHAIN& aPath, SEGMENTS& aOutSegment,
|
||||
float aBiuTo3DunitsScale )
|
||||
{
|
||||
aOutSegment.resize( aPath.PointCount() );
|
||||
|
||||
for( int j = 0; j < aPath.PointCount(); j++ )
|
||||
{
|
||||
const VECTOR2I &a = aPath.CPoint( j );
|
||||
const VECTOR2I& a = aPath.CPoint( j );
|
||||
|
||||
aOutSegment[j].m_Start = SFVEC2F( (float) a.x * aBiuTo3DunitsScale,
|
||||
(float)-a.y * aBiuTo3DunitsScale );
|
||||
(float) -a.y * aBiuTo3DunitsScale );
|
||||
}
|
||||
|
||||
unsigned int i;
|
||||
unsigned int j = aOutSegment.size () - 1;
|
||||
unsigned int j = aOutSegment.size() - 1;
|
||||
|
||||
for( i = 0; i < aOutSegment.size (); j = i++ )
|
||||
for( i = 0; i < aOutSegment.size(); j = i++ )
|
||||
{
|
||||
// Calculate constants for each segment
|
||||
aOutSegment[i].m_inv_JY_minus_IY = 1.0f / ( aOutSegment[j].m_Start.y -
|
||||
aOutSegment[i].m_Start.y );
|
||||
aOutSegment[i].m_inv_JY_minus_IY = 1.0f /
|
||||
( aOutSegment[j].m_Start.y - aOutSegment[i].m_Start.y );
|
||||
|
||||
aOutSegment[i].m_JX_minus_IX = (aOutSegment[j].m_Start.x -
|
||||
aOutSegment[i].m_Start.x);
|
||||
aOutSegment[i].m_JX_minus_IX = ( aOutSegment[j].m_Start.x - aOutSegment[i].m_Start.x );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
||||
const SHAPE_POLY_SET &aMainPath,
|
||||
CGENERICCONTAINER2D &aDstContainer,
|
||||
float aBiuTo3DunitsScale,
|
||||
float aDivFactor,
|
||||
const BOARD_ITEM &aBoardItem,
|
||||
int aPolyIndex )
|
||||
void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks( const SHAPE_POLY_SET& aMainPath,
|
||||
CGENERICCONTAINER2D& aDstContainer, float aBiuTo3DunitsScale, float aDivFactor,
|
||||
const BOARD_ITEM& aBoardItem, int aPolyIndex )
|
||||
{
|
||||
// Get the path
|
||||
|
||||
wxASSERT( aPolyIndex < aMainPath.OutlineCount() );
|
||||
|
||||
const SHAPE_LINE_CHAIN& path = aMainPath.COutline( aPolyIndex );
|
||||
|
@ -438,13 +409,12 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
{
|
||||
const VECTOR2I& a = path.CPoint( i );
|
||||
|
||||
const SFVEC2F point ( (float)( a.x) * aBiuTo3DunitsScale,
|
||||
(float)(-a.y) * aBiuTo3DunitsScale );
|
||||
const SFVEC2F point( (float) ( a.x ) * aBiuTo3DunitsScale,
|
||||
(float) ( -a.y ) * aBiuTo3DunitsScale );
|
||||
|
||||
// Only add points that are not coincident
|
||||
if( (i == 0) ||
|
||||
(fabs(prevPoint.x - point.x) > FLT_EPSILON) ||
|
||||
(fabs(prevPoint.y - point.y) > FLT_EPSILON) )
|
||||
if( ( i == 0 ) || ( fabs( prevPoint.x - point.x ) > FLT_EPSILON )
|
||||
|| ( fabs( prevPoint.y - point.y ) > FLT_EPSILON ) )
|
||||
{
|
||||
prevPoint = point;
|
||||
|
||||
|
@ -462,33 +432,32 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
|
||||
bbox.ScaleNextUp();
|
||||
|
||||
|
||||
// Calc the slopes, normals and some statistics about this polygon
|
||||
unsigned int i;
|
||||
unsigned int j = segments_and_normals.size() - 1;
|
||||
|
||||
// Temporary normal to the segment, it will later be used for interpolation
|
||||
std::vector< SFVEC2F > tmpSegmentNormals;
|
||||
std::vector<SFVEC2F> tmpSegmentNormals;
|
||||
tmpSegmentNormals.resize( segments_and_normals.size() );
|
||||
|
||||
float medOfTheSquaresSegmentLength = 0.0f;
|
||||
|
||||
#ifdef PRINT_STATISTICS_3D_VIEWER
|
||||
float minLength = FLT_MAX;
|
||||
#endif
|
||||
|
||||
for( i = 0; i < segments_and_normals.size(); j = i++ )
|
||||
{
|
||||
const SFVEC2F slope = segments_and_normals[j].m_Start -
|
||||
segments_and_normals[i].m_Start;
|
||||
const SFVEC2F slope = segments_and_normals[j].m_Start - segments_and_normals[i].m_Start;
|
||||
|
||||
segments_and_normals[i].m_Precalc_slope = slope;
|
||||
|
||||
// Calculate constants for each segment
|
||||
segments[i].m_inv_JY_minus_IY = 1.0f / ( segments_and_normals[j].m_Start.y -
|
||||
segments_and_normals[i].m_Start.y );
|
||||
segments[i].m_inv_JY_minus_IY =
|
||||
1.0f / ( segments_and_normals[j].m_Start.y - segments_and_normals[i].m_Start.y );
|
||||
|
||||
segments[i].m_JX_minus_IX = ( segments_and_normals[j].m_Start.x -
|
||||
segments_and_normals[i].m_Start.x );
|
||||
segments[i].m_JX_minus_IX =
|
||||
( segments_and_normals[j].m_Start.x - segments_and_normals[i].m_Start.x );
|
||||
|
||||
// The normal orientation expect a fixed polygon orientation (!TODO: which one?)
|
||||
//tmpSegmentNormals[i] = glm::normalize( SFVEC2F( -slope.y, +slope.x ) );
|
||||
|
@ -513,33 +482,32 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
medOfTheSquaresSegmentLength /= segments_and_normals.size();
|
||||
medOfTheSquaresSegmentLength = sqrt( medOfTheSquaresSegmentLength );
|
||||
|
||||
|
||||
// Compute the normal interpolation
|
||||
// If calculate the dot between the segments, if they are above/below some
|
||||
// threshould it will not interpolated it (ex: if you are in a edge corner
|
||||
// threshold it will not interpolated it (ex: if you are in a edge corner
|
||||
// or in a smooth transaction)
|
||||
j = segments_and_normals.size() - 1;
|
||||
|
||||
for( i = 0; i < segments_and_normals.size(); j = i++ )
|
||||
{
|
||||
const SFVEC2F normalBeforeSeg = tmpSegmentNormals[j];
|
||||
const SFVEC2F normalSeg = tmpSegmentNormals[i];
|
||||
const SFVEC2F normalAfterSeg = tmpSegmentNormals[ (i + 1) %
|
||||
segments_and_normals.size() ];
|
||||
const SFVEC2F normalAfterSeg = tmpSegmentNormals[( i + 1 ) % segments_and_normals.size()];
|
||||
|
||||
const float dotBefore = glm::dot( normalBeforeSeg, normalSeg );
|
||||
const float dotAfter = glm::dot( normalAfterSeg, normalSeg );
|
||||
const float dotAfter = glm::dot( normalAfterSeg, normalSeg );
|
||||
|
||||
if( dotBefore < 0.7f )
|
||||
segments_and_normals[i].m_Normals.m_Start = normalSeg;
|
||||
else
|
||||
segments_and_normals[i].m_Normals.m_Start =
|
||||
glm::normalize( (normalBeforeSeg * dotBefore ) + normalSeg );
|
||||
glm::normalize( ( normalBeforeSeg * dotBefore ) + normalSeg );
|
||||
|
||||
if( dotAfter < 0.7f )
|
||||
segments_and_normals[i].m_Normals.m_End = normalSeg;
|
||||
else
|
||||
segments_and_normals[i].m_Normals.m_End =
|
||||
glm::normalize( (normalAfterSeg * dotAfter ) + normalSeg );
|
||||
glm::normalize( ( normalAfterSeg * dotAfter ) + normalSeg );
|
||||
}
|
||||
|
||||
SFVEC2UI grid_divisions;
|
||||
|
@ -553,55 +521,46 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
if( aDivFactor <= FLT_EPSILON )
|
||||
aDivFactor = medOfTheSquaresSegmentLength;
|
||||
|
||||
grid_divisions.x = (unsigned int) ( ( bbox.GetExtent().x / aDivFactor ) );
|
||||
grid_divisions.y = (unsigned int) ( ( bbox.GetExtent().y / aDivFactor ) );
|
||||
|
||||
grid_divisions.x = (unsigned int)( ( bbox.GetExtent().x / aDivFactor ) );
|
||||
grid_divisions.y = (unsigned int)( ( bbox.GetExtent().y / aDivFactor ) );
|
||||
|
||||
grid_divisions = glm::clamp( grid_divisions ,
|
||||
SFVEC2UI( 1, 1 ),
|
||||
SFVEC2UI( MAX_NR_DIVISIONS, MAX_NR_DIVISIONS ) );
|
||||
grid_divisions = glm::clamp(
|
||||
grid_divisions, SFVEC2UI( 1, 1 ), SFVEC2UI( MAX_NR_DIVISIONS, MAX_NR_DIVISIONS ) );
|
||||
}
|
||||
|
||||
// Calculate the steps advance of the grid
|
||||
SFVEC2F blockAdvance;
|
||||
|
||||
blockAdvance.x = bbox.GetExtent().x / (float)grid_divisions.x;
|
||||
blockAdvance.y = bbox.GetExtent().y / (float)grid_divisions.y;
|
||||
blockAdvance.x = bbox.GetExtent().x / (float) grid_divisions.x;
|
||||
blockAdvance.y = bbox.GetExtent().y / (float) grid_divisions.y;
|
||||
|
||||
wxASSERT( blockAdvance.x > 0.0f );
|
||||
wxASSERT( blockAdvance.y > 0.0f );
|
||||
|
||||
const int leftToRight_inc = (pathBounds.GetRight() - pathBounds.GetLeft()) /
|
||||
grid_divisions.x;
|
||||
const int leftToRight_inc = ( pathBounds.GetRight() - pathBounds.GetLeft() ) / grid_divisions.x;
|
||||
|
||||
const int topToBottom_inc = (pathBounds.GetBottom() - pathBounds.GetTop()) /
|
||||
grid_divisions.y;
|
||||
const int topToBottom_inc = ( pathBounds.GetBottom() - pathBounds.GetTop() ) / grid_divisions.y;
|
||||
|
||||
// Statistics
|
||||
unsigned int stats_n_empty_blocks = 0;
|
||||
unsigned int stats_n_dummy_blocks = 0;
|
||||
unsigned int stats_n_poly_blocks = 0;
|
||||
unsigned int stats_n_empty_blocks = 0;
|
||||
unsigned int stats_n_dummy_blocks = 0;
|
||||
unsigned int stats_n_poly_blocks = 0;
|
||||
unsigned int stats_sum_size_of_polygons = 0;
|
||||
|
||||
|
||||
// Step by each block of a grid trying to extract segments and create
|
||||
// polygon blocks
|
||||
|
||||
int topToBottom = pathBounds.GetTop();
|
||||
float blockY = bbox.Max().y;
|
||||
// Step by each block of a grid trying to extract segments and create polygon blocks
|
||||
int topToBottom = pathBounds.GetTop();
|
||||
float blockY = bbox.Max().y;
|
||||
|
||||
for( unsigned int iy = 0; iy < grid_divisions.y; iy++ )
|
||||
{
|
||||
|
||||
int leftToRight = pathBounds.GetLeft();
|
||||
float blockX = bbox.Min().x;
|
||||
int leftToRight = pathBounds.GetLeft();
|
||||
float blockX = bbox.Min().x;
|
||||
|
||||
for( unsigned int ix = 0; ix < grid_divisions.x; ix++ )
|
||||
{
|
||||
CBBOX2D blockBox( SFVEC2F( blockX,
|
||||
blockY - blockAdvance.y ),
|
||||
SFVEC2F( blockX + blockAdvance.x,
|
||||
blockY ) );
|
||||
CBBOX2D blockBox( SFVEC2F( blockX, blockY - blockAdvance.y ),
|
||||
SFVEC2F( blockX + blockAdvance.x, blockY ) );
|
||||
|
||||
// Make the box large to it will catch (intersect) the edges
|
||||
blockBox.ScaleNextUp();
|
||||
|
@ -612,7 +571,6 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
|
||||
extractPathsFrom( segments_and_normals, blockBox, extractedSegments );
|
||||
|
||||
|
||||
if( extractedSegments.empty() )
|
||||
{
|
||||
|
||||
|
@ -621,22 +579,20 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
SFVEC2F p3( blockBox.Max().x, blockBox.Max().y );
|
||||
SFVEC2F p4( blockBox.Min().x, blockBox.Max().y );
|
||||
|
||||
if( polygon_IsPointInside( segments, p1 ) ||
|
||||
polygon_IsPointInside( segments, p2 ) ||
|
||||
polygon_IsPointInside( segments, p3 ) ||
|
||||
polygon_IsPointInside( segments, p4 ) )
|
||||
if( polygon_IsPointInside( segments, p1 ) || polygon_IsPointInside( segments, p2 )
|
||||
|| polygon_IsPointInside( segments, p3 )
|
||||
|| polygon_IsPointInside( segments, p4 ) )
|
||||
{
|
||||
// In this case, the segments are not intersecting the
|
||||
// polygon, so it means that if any point is inside it,
|
||||
// then all other are inside the polygon.
|
||||
// This is a full bbox inside, so add a dummy box
|
||||
|
||||
aDstContainer.Add( new CDUMMYBLOCK2D( blockBox, aBoardItem ) );
|
||||
stats_n_dummy_blocks++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Points are outside, so this block complety missed the polygon
|
||||
// Points are outside, so this block completely missed the polygon
|
||||
// In this case, no objects need to be added
|
||||
stats_n_empty_blocks++;
|
||||
}
|
||||
|
@ -663,9 +619,8 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
|
||||
// We need here a strictly simple polygon with outlines and holes
|
||||
SHAPE_POLY_SET solution;
|
||||
solution.BooleanIntersection( aMainPath,
|
||||
subBlockPoly,
|
||||
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
solution.BooleanIntersection(
|
||||
aMainPath, subBlockPoly, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
|
||||
OUTERS_AND_HOLES outersAndHoles;
|
||||
|
||||
|
@ -674,7 +629,7 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
|
||||
for( int idx = 0; idx < solution.OutlineCount(); idx++ )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN & outline = solution.Outline( idx );
|
||||
const SHAPE_LINE_CHAIN& outline = solution.Outline( idx );
|
||||
|
||||
SEGMENTS solutionSegment;
|
||||
|
||||
|
@ -683,23 +638,19 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
|
||||
stats_sum_size_of_polygons += solutionSegment.size();
|
||||
|
||||
for( int holeIdx = 0;
|
||||
holeIdx < solution.HoleCount( idx );
|
||||
holeIdx++ )
|
||||
for( int holeIdx = 0; holeIdx < solution.HoleCount( idx ); holeIdx++ )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN & hole = solution.Hole( idx, holeIdx );
|
||||
const SHAPE_LINE_CHAIN& hole = solution.Hole( idx, holeIdx );
|
||||
|
||||
polygon_Convert( hole, solutionSegment, aBiuTo3DunitsScale );
|
||||
outersAndHoles.m_Holes.push_back( solutionSegment );
|
||||
stats_sum_size_of_polygons += solutionSegment.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( !outersAndHoles.m_Outers.empty() )
|
||||
{
|
||||
aDstContainer.Add( new CPOLYGONBLOCK2D( extractedSegments,
|
||||
outersAndHoles,
|
||||
aDstContainer.Add( new CPOLYGONBLOCK2D( extractedSegments, outersAndHoles,
|
||||
aBoardItem ) );
|
||||
stats_n_poly_blocks++;
|
||||
}
|
||||
|
@ -716,30 +667,30 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
|||
|
||||
|
||||
#ifdef DEBUG
|
||||
static void polygon_Convert( const ClipperLib::Path &aPath,
|
||||
SEGMENTS &aOutSegment,
|
||||
static void polygon_Convert( const ClipperLib::Path& aPath, SEGMENTS& aOutSegment,
|
||||
float aBiuTo3DunitsScale )
|
||||
{
|
||||
aOutSegment.resize( aPath.size() );
|
||||
|
||||
for( unsigned i = 0; i < aPath.size(); i++ )
|
||||
{
|
||||
aOutSegment[i].m_Start = SFVEC2F( (float) aPath[i].X * aBiuTo3DunitsScale,
|
||||
(float)-aPath[i].Y * aBiuTo3DunitsScale );
|
||||
aOutSegment[i].m_Start = SFVEC2F(
|
||||
(float) aPath[i].X * aBiuTo3DunitsScale, (float) -aPath[i].Y * aBiuTo3DunitsScale );
|
||||
}
|
||||
|
||||
unsigned int i;
|
||||
unsigned int j = aOutSegment.size () - 1;
|
||||
unsigned int j = aOutSegment.size() - 1;
|
||||
|
||||
for( i = 0; i < aOutSegment.size (); j = i++ )
|
||||
for( i = 0; i < aOutSegment.size(); j = i++ )
|
||||
{
|
||||
// Calculate constants for each segment
|
||||
aOutSegment[i].m_inv_JY_minus_IY = 1.0f / ( aOutSegment[j].m_Start.y -
|
||||
aOutSegment[i].m_Start.y );
|
||||
aOutSegment[i].m_JX_minus_IX = (aOutSegment[j].m_Start.x - aOutSegment[i].m_Start.x);
|
||||
aOutSegment[i].m_inv_JY_minus_IY =
|
||||
1.0f / ( aOutSegment[j].m_Start.y - aOutSegment[i].m_Start.y );
|
||||
aOutSegment[i].m_JX_minus_IX = ( aOutSegment[j].m_Start.x - aOutSegment[i].m_Start.x );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Polygon2d_TestModule()
|
||||
{
|
||||
// "This structure contains a sequence of IntPoint vertices defining a
|
||||
|
@ -751,9 +702,9 @@ void Polygon2d_TestModule()
|
|||
aPath.resize( 4 );
|
||||
|
||||
aPath[0] = ClipperLib::IntPoint( -2, -2 );
|
||||
aPath[1] = ClipperLib::IntPoint( 2, -2 );
|
||||
aPath[2] = ClipperLib::IntPoint( 2, 2 );
|
||||
aPath[3] = ClipperLib::IntPoint( -2, 2 );
|
||||
aPath[1] = ClipperLib::IntPoint( 2, -2 );
|
||||
aPath[2] = ClipperLib::IntPoint( 2, 2 );
|
||||
aPath[3] = ClipperLib::IntPoint( -2, 2 );
|
||||
|
||||
// It must be an outer polygon
|
||||
wxASSERT( ClipperLib::Orientation( aPath ) );
|
||||
|
@ -762,20 +713,20 @@ void Polygon2d_TestModule()
|
|||
|
||||
wxASSERT( aPath.size() == aSegments.size() );
|
||||
|
||||
wxASSERT( aSegments[0].m_Start == SFVEC2F( -2.0f, 2.0f ) );
|
||||
wxASSERT( aSegments[1].m_Start == SFVEC2F( 2.0f, 2.0f ) );
|
||||
wxASSERT( aSegments[2].m_Start == SFVEC2F( 2.0f, -2.0f ) );
|
||||
wxASSERT( aSegments[0].m_Start == SFVEC2F( -2.0f, 2.0f ) );
|
||||
wxASSERT( aSegments[1].m_Start == SFVEC2F( 2.0f, 2.0f ) );
|
||||
wxASSERT( aSegments[2].m_Start == SFVEC2F( 2.0f, -2.0f ) );
|
||||
wxASSERT( aSegments[3].m_Start == SFVEC2F( -2.0f, -2.0f ) );
|
||||
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 0.0f, 0.0f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 0.0f, 0.0f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -1.9f, -1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -1.9f, 1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 1.9f, 1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 1.9f, -1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -1.9f, 1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 1.9f, 1.9f ) ) );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 1.9f, -1.9f ) ) );
|
||||
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -2.1f, -2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -2.1f, 2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 2.1f, 2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 2.1f, -2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( -2.1f, 2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 2.1f, 2.0f ) ) == false );
|
||||
wxASSERT( polygon_IsPointInside( aSegments, SFVEC2F( 2.1f, -2.0f ) ) == false );
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -41,14 +41,14 @@ typedef struct
|
|||
SFVEC2F m_Start;
|
||||
float m_inv_JY_minus_IY;
|
||||
float m_JX_minus_IX;
|
||||
}POLYSEGMENT;
|
||||
} POLYSEGMENT;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SFVEC2F m_Start;
|
||||
SFVEC2F m_End;
|
||||
}SEG_NORMALS;
|
||||
} SEG_NORMALS;
|
||||
|
||||
|
||||
typedef struct
|
||||
|
@ -56,45 +56,43 @@ typedef struct
|
|||
SFVEC2F m_Start;
|
||||
SFVEC2F m_Precalc_slope;
|
||||
SEG_NORMALS m_Normals;
|
||||
}SEGMENT_WITH_NORMALS;
|
||||
} SEGMENT_WITH_NORMALS;
|
||||
|
||||
|
||||
typedef std::vector< POLYSEGMENT > SEGMENTS;
|
||||
|
||||
|
||||
/// This list will be used to test ray2d intersections. It will be a subset
|
||||
/// of an original polygon. The normals will be passed already interpolated.
|
||||
/**
|
||||
* List used to test ray2d intersections.
|
||||
*
|
||||
* It will be a subset of an original polygon. The normals will be passed already interpolated.
|
||||
*/
|
||||
typedef std::vector< SEGMENT_WITH_NORMALS > SEGMENTS_WIDTH_NORMALS;
|
||||
|
||||
|
||||
/// This structured will be used to handle a sub set of a polygon.
|
||||
/// It can contain multiple closed polygons and holes.
|
||||
/// It will be used to test if points are inside. A point will be inside the
|
||||
/// polygon if it is not inside a hole and it is inside a Outer polygon.
|
||||
/**
|
||||
* Handle a subset of a polygon.
|
||||
*
|
||||
* It can contain multiple closed polygons and holes and us used to test if points are inside.
|
||||
* A point will be inside the polygon if it is not inside a hole and it is inside an outer polygon.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
std::vector<SEGMENTS> m_Outers;
|
||||
std::vector<SEGMENTS> m_Holes;
|
||||
}OUTERS_AND_HOLES;
|
||||
} OUTERS_AND_HOLES;
|
||||
|
||||
|
||||
/// This class represents a sub polygon block. This polygon block was created
|
||||
/// from a general polygon definition that was sub divided and create blocks of
|
||||
/// polygons. This polygon class represent a sub part of that main polygon.
|
||||
/// There is information for the contours (used to test the ray2d intersection)
|
||||
/// and a close definition of the block polygon to test if a point is inside.
|
||||
/**
|
||||
* Represent a sub polygon block.
|
||||
*
|
||||
* This polygon block was created from a general polygon definition that was sub divided and
|
||||
* to create blocks of polygons. This polygon class represent a sub part of that main polygon.
|
||||
* There is information for the contours (used to test the ray2d intersection) and a close
|
||||
* definition of the block polygon to test if a point is inside.
|
||||
*/
|
||||
class CPOLYGONBLOCK2D : public COBJECT2D
|
||||
{
|
||||
private:
|
||||
/// This is the outer part of the polygon. This list is used to test a ray
|
||||
/// intersection with the boundaries of this sub polygon.
|
||||
/// It contains also the interpolated normals that are passed from the main
|
||||
/// polygon.
|
||||
SEGMENTS_WIDTH_NORMALS m_open_segments;
|
||||
|
||||
/// A polygon block can have multiple polygon and holes
|
||||
OUTERS_AND_HOLES m_outers_and_holes;
|
||||
|
||||
public:
|
||||
CPOLYGONBLOCK2D( const SEGMENTS_WIDTH_NORMALS &aOpenSegmentList,
|
||||
const OUTERS_AND_HOLES &aOuter_and_holes,
|
||||
|
@ -106,17 +104,30 @@ public:
|
|||
bool Intersect( const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut ) const override;
|
||||
INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const override;
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The outer part of the polygon.
|
||||
*
|
||||
* This list is used to test a ray intersection with the boundaries of this sub polygon.
|
||||
* It contains also the interpolated normals that are passed from the main polygon.
|
||||
*/
|
||||
SEGMENTS_WIDTH_NORMALS m_open_segments;
|
||||
|
||||
///< A polygon block can have multiple polygon and holes
|
||||
OUTERS_AND_HOLES m_outers_and_holes;
|
||||
};
|
||||
|
||||
|
||||
/// This dummy block will be defined by a 2d box size. If the point is inside
|
||||
/// the bounding box it will return allways true. However, the intersection with
|
||||
/// a ray will return allways false.
|
||||
/// This is used as a sub block extrated from polygon (pcb polygon areas) and
|
||||
/// represents an area that is full filled.
|
||||
/**
|
||||
* A dummy block defined by a 2d box size.
|
||||
*
|
||||
* If the point is inside the bounding box it will return always true. However, the
|
||||
* intersection with a ray will return always false. This is used as a sub block
|
||||
* extracted from polygon (pcb polygon areas) and represents an area that is full filled.
|
||||
*/
|
||||
class CDUMMYBLOCK2D : public COBJECT2D
|
||||
{
|
||||
|
||||
public:
|
||||
CDUMMYBLOCK2D( const SFVEC2F &aPbMin,
|
||||
const SFVEC2F &aPbMax,
|
||||
|
@ -132,16 +143,16 @@ public:
|
|||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convert_path_polygon_to_polygon_blocks_and_dummy_blocks
|
||||
* This function will use a polygon in the format of the ClipperLib::Path
|
||||
* will process it and will create multiple 2d objects (CPOLYGONBLOCK2D and
|
||||
* CDUMMYBLOCK2D) that can be used to represent this polygon area.
|
||||
* @param aMainPath - the polygon are that was converted from the pcb board
|
||||
* @param aDstContainer - the destination container to put the created sub blocks
|
||||
* @param aBiuTo3DunitsScale - the rendering target 3d scale
|
||||
* @param aDivFactor - a division factor (in 3Dunits) to divide the polygon plane,
|
||||
* 0.0f will use the internal polygon segm statistics
|
||||
* Use a polygon in the format of the ClipperLib::Path and process it and create multiple 2d
|
||||
* objects (CPOLYGONBLOCK2D and CDUMMYBLOCK2D) that can be used to represent this polygon area.
|
||||
*
|
||||
* @param aMainPath the polygon are that was converted from the pcb board
|
||||
* @param aDstContainer the destination container to put the created sub blocks
|
||||
* @param aBiuTo3DunitsScale the rendering target 3d scale
|
||||
* @param aDivFactor a division factor (in 3Dunits) to divide the polygon plane,
|
||||
* 0.0f will use the internal polygon segm statistics
|
||||
*/
|
||||
void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
||||
const SHAPE_POLY_SET &aMainPath,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -32,9 +32,9 @@
|
|||
|
||||
|
||||
CPOLYGON4PTS2D::CPOLYGON4PTS2D( const SFVEC2F& v1, const SFVEC2F& v2, const SFVEC2F& v3,
|
||||
const SFVEC2F& v4, const BOARD_ITEM& aBoardItem )
|
||||
: COBJECT2D( OBJECT2D_TYPE::POLYGON4PT, aBoardItem )
|
||||
{/*
|
||||
const SFVEC2F& v4, const BOARD_ITEM& aBoardItem ) :
|
||||
COBJECT2D( OBJECT2D_TYPE::POLYGON4PT, aBoardItem )
|
||||
{ /*
|
||||
if( (v1.x > v2.x) || (v1.y < v2.y) )
|
||||
{
|
||||
m_segments[0] = v4;
|
||||
|
@ -44,20 +44,20 @@ CPOLYGON4PTS2D::CPOLYGON4PTS2D( const SFVEC2F& v1, const SFVEC2F& v2, const SFVE
|
|||
}
|
||||
else
|
||||
{*/
|
||||
m_segments[0] = v1;
|
||||
m_segments[1] = v4;
|
||||
m_segments[2] = v3;
|
||||
m_segments[3] = v2;
|
||||
// }
|
||||
m_segments[0] = v1;
|
||||
m_segments[1] = v4;
|
||||
m_segments[2] = v3;
|
||||
m_segments[3] = v2;
|
||||
// }
|
||||
|
||||
unsigned int i;
|
||||
unsigned int j = 4 - 1;
|
||||
|
||||
for( i = 0; i < 4; j = i++ )
|
||||
{
|
||||
SFVEC2F slope = m_segments[j] - m_segments[i];
|
||||
SFVEC2F slope = m_segments[j] - m_segments[i];
|
||||
m_precalc_slope[i] = slope;
|
||||
m_seg_normal[i] = glm::normalize( SFVEC2F( -slope.y, +slope.x ) );
|
||||
m_seg_normal[i] = glm::normalize( SFVEC2F( -slope.y, +slope.x ) );
|
||||
}
|
||||
|
||||
m_bbox.Reset();
|
||||
|
@ -76,7 +76,7 @@ CPOLYGON4PTS2D::CPOLYGON4PTS2D( const SFVEC2F& v1, const SFVEC2F& v2, const SFVE
|
|||
}
|
||||
|
||||
|
||||
bool CPOLYGON4PTS2D::Intersects( const CBBOX2D &aBBox ) const
|
||||
bool CPOLYGON4PTS2D::Intersects( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
return m_bbox.Intersects( aBBox );
|
||||
|
||||
|
@ -125,37 +125,37 @@ bool CPOLYGON4PTS2D::Intersects( const CBBOX2D &aBBox ) const
|
|||
}
|
||||
|
||||
|
||||
bool CPOLYGON4PTS2D::Overlaps( const CBBOX2D &aBBox ) const
|
||||
bool CPOLYGON4PTS2D::Overlaps( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
// NOT IMPLEMENTED
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CPOLYGON4PTS2D::Intersect( const RAYSEG2D &aSegRay,
|
||||
float *aOutT,
|
||||
SFVEC2F *aNormalOut ) const
|
||||
bool CPOLYGON4PTS2D::Intersect( const RAYSEG2D& aSegRay, float* aOutT, SFVEC2F* aNormalOut ) const
|
||||
{
|
||||
bool hited = false;
|
||||
bool hited = false;
|
||||
unsigned int hitIndex;
|
||||
float bestHitT;
|
||||
float bestHitT;
|
||||
|
||||
for( unsigned int i = 0; i < 4; i++ )
|
||||
{
|
||||
float t;
|
||||
|
||||
if( aSegRay.IntersectSegment( m_segments[i], m_precalc_slope[i], &t ) )
|
||||
if( (hited == false) || ( t < bestHitT) )
|
||||
{
|
||||
if( ( hited == false ) || ( t < bestHitT ) )
|
||||
{
|
||||
hited = true;
|
||||
hited = true;
|
||||
hitIndex = i;
|
||||
bestHitT = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( hited )
|
||||
{
|
||||
wxASSERT( (bestHitT >= 0.0f) && (bestHitT <= 1.0f) );
|
||||
wxASSERT( ( bestHitT >= 0.0f ) && ( bestHitT <= 1.0f ) );
|
||||
|
||||
if( aOutT )
|
||||
*aOutT = bestHitT;
|
||||
|
@ -170,7 +170,7 @@ bool CPOLYGON4PTS2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
}
|
||||
|
||||
|
||||
INTERSECTION_RESULT CPOLYGON4PTS2D::IsBBoxInside( const CBBOX2D &aBBox ) const
|
||||
INTERSECTION_RESULT CPOLYGON4PTS2D::IsBBoxInside( const CBBOX2D& aBBox ) const
|
||||
{
|
||||
// !TODO:
|
||||
|
||||
|
@ -178,29 +178,28 @@ INTERSECTION_RESULT CPOLYGON4PTS2D::IsBBoxInside( const CBBOX2D &aBBox ) const
|
|||
}
|
||||
|
||||
|
||||
bool CPOLYGON4PTS2D::IsPointInside( const SFVEC2F &aPoint ) const
|
||||
bool CPOLYGON4PTS2D::IsPointInside( const SFVEC2F& aPoint ) const
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int j = 4 - 1;
|
||||
bool oddNodes = false;
|
||||
unsigned int j = 4 - 1;
|
||||
bool oddNodes = false;
|
||||
|
||||
for( i = 0; i < 4; j = i++ )
|
||||
{
|
||||
const float polyJY = m_segments[j].y;
|
||||
const float polyIY = m_segments[i].y;
|
||||
|
||||
if( ((polyIY <= aPoint.y) && (polyJY >= aPoint.y)) ||
|
||||
((polyJY <= aPoint.y) && (polyIY >= aPoint.y))
|
||||
)
|
||||
if( ( ( polyIY <= aPoint.y ) && ( polyJY >= aPoint.y ) )
|
||||
|| ( ( polyJY <= aPoint.y ) && ( polyIY >= aPoint.y ) ) )
|
||||
{
|
||||
const float polyJX = m_segments[j].x;
|
||||
const float polyIX = m_segments[i].x;
|
||||
|
||||
if( (polyIX <= aPoint.x) || (polyJX <= aPoint.x) )
|
||||
if( ( polyIX <= aPoint.x ) || ( polyJX <= aPoint.x ) )
|
||||
{
|
||||
oddNodes ^= ( ( polyIX +
|
||||
( ( aPoint.y - polyIY ) / ( polyJY - polyIY ) ) *
|
||||
( polyJX - polyIX ) ) < aPoint.x );
|
||||
oddNodes ^= ( ( polyIX + ( ( aPoint.y - polyIY ) / ( polyJY - polyIY ) )
|
||||
* ( polyJX - polyIX ) )
|
||||
< aPoint.x );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -33,17 +33,13 @@
|
|||
#include "cobject2d.h"
|
||||
|
||||
/**
|
||||
* This handles simple polygons with 4 points. Used for pads.
|
||||
* (rectangles, trapezoids, with rotation.etc)
|
||||
* This is a simplified version of the cpolygon2d class
|
||||
* Simple polygons with 4 points.
|
||||
*
|
||||
* Used for footprint pads. (rectangles, trapezoids, with rotation.etc). This is a
|
||||
* simplified version of the #CPOLYGON2D class.
|
||||
*/
|
||||
class CPOLYGON4PTS2D : public COBJECT2D
|
||||
{
|
||||
private:
|
||||
SFVEC2F m_segments[4];
|
||||
SFVEC2F m_precalc_slope[4];
|
||||
SFVEC2F m_seg_normal[4];
|
||||
|
||||
public:
|
||||
CPOLYGON4PTS2D( const SFVEC2F &v1,
|
||||
const SFVEC2F &v2,
|
||||
|
@ -67,6 +63,11 @@ public:
|
|||
bool Intersect( const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut ) const override;
|
||||
INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const override;
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
|
||||
private:
|
||||
SFVEC2F m_segments[4];
|
||||
SFVEC2F m_precalc_slope[4];
|
||||
SFVEC2F m_seg_normal[4];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -33,8 +33,8 @@
|
|||
|
||||
|
||||
CRING2D::CRING2D( const SFVEC2F& aCenter, float aInnerRadius, float aOuterRadius,
|
||||
const BOARD_ITEM& aBoardItem )
|
||||
: COBJECT2D( OBJECT2D_TYPE::RING, aBoardItem )
|
||||
const BOARD_ITEM& aBoardItem ) :
|
||||
COBJECT2D( OBJECT2D_TYPE::RING, aBoardItem )
|
||||
{
|
||||
wxASSERT( aInnerRadius < aOuterRadius );
|
||||
|
||||
|
@ -51,7 +51,6 @@ CRING2D::CRING2D( const SFVEC2F& aCenter, float aInnerRadius, float aOuterRadius
|
|||
m_bbox.ScaleNextUp();
|
||||
m_centroid = m_bbox.GetCenter();
|
||||
|
||||
|
||||
wxASSERT( m_bbox.IsInitialized() );
|
||||
}
|
||||
|
||||
|
@ -65,7 +64,7 @@ bool CRING2D::Overlaps( const CBBOX2D &aBBox ) const
|
|||
|
||||
bool CRING2D::Intersects( const CBBOX2D &aBBox ) const
|
||||
{
|
||||
// !TODO: check the inside for a great improovment
|
||||
// !TODO: check the inside for a great improvement
|
||||
return aBBox.Intersects( m_center, m_outer_radius_squared );
|
||||
}
|
||||
|
||||
|
@ -86,7 +85,6 @@ bool CRING2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
|
||||
// solving the quadratic equation for t at the pts of intersection
|
||||
// dd*t^2 + (2*qd)*t + (qq-r^2) = 0
|
||||
|
||||
const float discriminantsqr = qd * qd - qq;
|
||||
const float discriminantsqr_outer = discriminantsqr + m_outer_radius_squared;
|
||||
|
||||
|
@ -129,10 +127,14 @@ bool CRING2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
wxASSERT( (t > 0.0f) && (t <= aSegRay.m_Length) );
|
||||
|
@ -196,8 +198,7 @@ bool CRING2D::IsPointInside( const SFVEC2F &aPoint ) const
|
|||
|
||||
const float dot = glm::dot( v, v );
|
||||
|
||||
if( (dot <= m_outer_radius_squared) &&
|
||||
(dot >= m_inner_radius_squared) )
|
||||
if( (dot <= m_outer_radius_squared) && (dot >= m_inner_radius_squared) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -35,6 +35,16 @@
|
|||
class CRING2D : public COBJECT2D
|
||||
{
|
||||
public:
|
||||
CRING2D( const SFVEC2F &aCenter, float aInnerRadius, float aOuterRadius,
|
||||
const BOARD_ITEM &aBoardItem );
|
||||
|
||||
// Imported from COBJECT2D
|
||||
bool Overlaps( const CBBOX2D &aBBox ) const override;
|
||||
bool Intersects( const CBBOX2D &aBBox ) const override;
|
||||
bool Intersect( const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut ) const override;
|
||||
INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const override;
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
|
||||
const SFVEC2F &GetCenter() const { return m_center; }
|
||||
float GetInnerRadius() const { return m_inner_radius; }
|
||||
float GetOuterRadius() const { return m_outer_radius; }
|
||||
|
@ -48,17 +58,6 @@ private:
|
|||
float m_outer_radius;
|
||||
float m_inner_radius_squared;
|
||||
float m_outer_radius_squared;
|
||||
|
||||
public:
|
||||
CRING2D( const SFVEC2F &aCenter, float aInnerRadius, float aOuterRadius,
|
||||
const BOARD_ITEM &aBoardItem );
|
||||
|
||||
// Imported from COBJECT2D
|
||||
bool Overlaps( const CBBOX2D &aBBox ) const override;
|
||||
bool Intersects( const CBBOX2D &aBBox ) const override;
|
||||
bool Intersect( const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut ) const override;
|
||||
INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const override;
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -31,9 +31,10 @@
|
|||
#include <wx/debug.h>
|
||||
|
||||
|
||||
CROUNDSEGMENT2D::CROUNDSEGMENT2D(
|
||||
const SFVEC2F& aStart, const SFVEC2F& aEnd, float aWidth, const BOARD_ITEM& aBoardItem )
|
||||
: COBJECT2D( OBJECT2D_TYPE::ROUNDSEG, aBoardItem ), m_segment( aStart, aEnd )
|
||||
CROUNDSEGMENT2D::CROUNDSEGMENT2D( const SFVEC2F& aStart, const SFVEC2F& aEnd, float aWidth,
|
||||
const BOARD_ITEM& aBoardItem ) :
|
||||
COBJECT2D( OBJECT2D_TYPE::ROUNDSEG, aBoardItem ),
|
||||
m_segment( aStart, aEnd )
|
||||
{
|
||||
wxASSERT( aStart != aEnd );
|
||||
|
||||
|
@ -41,8 +42,7 @@ CROUNDSEGMENT2D::CROUNDSEGMENT2D(
|
|||
m_radius_squared = m_radius * m_radius;
|
||||
m_width = aWidth;
|
||||
|
||||
SFVEC2F leftRadiusOffset( -m_segment.m_Dir.y * m_radius,
|
||||
m_segment.m_Dir.x * m_radius );
|
||||
SFVEC2F leftRadiusOffset( -m_segment.m_Dir.y * m_radius, m_segment.m_Dir.x * m_radius );
|
||||
|
||||
m_leftStart = aStart + leftRadiusOffset;
|
||||
m_leftEnd = aEnd + leftRadiusOffset;
|
||||
|
@ -72,11 +72,8 @@ bool CROUNDSEGMENT2D::Intersects( const CBBOX2D &aBBox ) const
|
|||
if( !m_bbox.Intersects( aBBox ) )
|
||||
return false;
|
||||
|
||||
if( (aBBox.Max().x > m_bbox.Max().x) &&
|
||||
(aBBox.Max().y > m_bbox.Max().y) &&
|
||||
(aBBox.Min().x < m_bbox.Min().x) &&
|
||||
(aBBox.Min().y < m_bbox.Min().y)
|
||||
)
|
||||
if( ( aBBox.Max().x > m_bbox.Max().x ) && ( aBBox.Max().y > m_bbox.Max().y )
|
||||
&& ( aBBox.Min().x < m_bbox.Min().x ) && ( aBBox.Min().y < m_bbox.Min().y ) )
|
||||
return true;
|
||||
|
||||
SFVEC2F v[4];
|
||||
|
@ -172,20 +169,24 @@ bool CROUNDSEGMENT2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
if( rightSegmentHit )
|
||||
{
|
||||
if( !start_is_inside )
|
||||
if( (hitted == false) || (rightSegT < closerHitT) )
|
||||
{
|
||||
closerHitT = rightSegT;
|
||||
closerHitNormal = SFVEC2F( -m_rightDir.y, m_rightDir.x );
|
||||
}
|
||||
if( (hitted == false) || (rightSegT < closerHitT) )
|
||||
{
|
||||
closerHitT = rightSegT;
|
||||
closerHitNormal = SFVEC2F( -m_rightDir.y, m_rightDir.x );
|
||||
}
|
||||
|
||||
if( start_is_inside )
|
||||
if( (hitted == false) || (rightSegT > farHitT) )
|
||||
{
|
||||
farHitT = rightSegT;
|
||||
farHitNormal = SFVEC2F( -m_rightDir.y, m_rightDir.x );
|
||||
}
|
||||
if( start_is_inside )
|
||||
{
|
||||
if( (hitted == false) || (rightSegT > farHitT) )
|
||||
{
|
||||
farHitT = rightSegT;
|
||||
farHitNormal = SFVEC2F( -m_rightDir.y, m_rightDir.x );
|
||||
}
|
||||
}
|
||||
|
||||
hitted = true;
|
||||
hitted = true;
|
||||
}
|
||||
}
|
||||
|
||||
float circleStart_T0;
|
||||
|
@ -202,17 +203,21 @@ bool CROUNDSEGMENT2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
if( circleStart_T0 > 0.0f )
|
||||
{
|
||||
if( !start_is_inside )
|
||||
if( (hitted == false) || (circleStart_T0 < closerHitT) )
|
||||
{
|
||||
closerHitT = circleStart_T0;
|
||||
closerHitNormal = circleStart_N0;
|
||||
if( (hitted == false) || (circleStart_T0 < closerHitT) )
|
||||
{
|
||||
closerHitT = circleStart_T0;
|
||||
closerHitNormal = circleStart_N0;
|
||||
}
|
||||
}
|
||||
|
||||
if( start_is_inside )
|
||||
if( (hitted == false) || (circleStart_T1 > farHitT) )
|
||||
{
|
||||
farHitT = circleStart_T1;
|
||||
farHitNormal = circleStart_N1;
|
||||
if( (hitted == false) || (circleStart_T1 > farHitT) )
|
||||
{
|
||||
farHitT = circleStart_T1;
|
||||
farHitNormal = circleStart_N1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -241,17 +246,21 @@ bool CROUNDSEGMENT2D::Intersect( const RAYSEG2D &aSegRay,
|
|||
if( circleEnd_T0 > 0.0f )
|
||||
{
|
||||
if( !start_is_inside )
|
||||
if( (hitted == false) || (circleEnd_T0 < closerHitT) )
|
||||
{
|
||||
closerHitT = circleEnd_T0;
|
||||
closerHitNormal = circleEnd_N0;
|
||||
if( (hitted == false) || (circleEnd_T0 < closerHitT) )
|
||||
{
|
||||
closerHitT = circleEnd_T0;
|
||||
closerHitNormal = circleEnd_N0;
|
||||
}
|
||||
}
|
||||
|
||||
if( start_is_inside )
|
||||
if( (hitted == false) || (circleEnd_T1 > farHitT) )
|
||||
{
|
||||
farHitT = circleEnd_T1;
|
||||
farHitNormal = circleEnd_N1;
|
||||
if( (hitted == false) || (circleEnd_T1 > farHitT) )
|
||||
{
|
||||
farHitT = circleEnd_T1;
|
||||
farHitNormal = circleEnd_N1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -37,23 +37,6 @@ class CROUNDSEGMENT2D : public COBJECT2D
|
|||
|
||||
friend class CROUNDSEG;
|
||||
|
||||
private:
|
||||
RAYSEG2D m_segment;
|
||||
|
||||
SFVEC2F m_leftStart;
|
||||
SFVEC2F m_leftEnd;
|
||||
SFVEC2F m_leftEndMinusStart;
|
||||
SFVEC2F m_leftDir;
|
||||
|
||||
SFVEC2F m_rightStart;
|
||||
SFVEC2F m_rightEnd;
|
||||
SFVEC2F m_rightEndMinusStart;
|
||||
SFVEC2F m_rightDir;
|
||||
|
||||
float m_radius;
|
||||
float m_radius_squared;
|
||||
float m_width;
|
||||
|
||||
public:
|
||||
CROUNDSEGMENT2D( const SFVEC2F &aStart, const SFVEC2F &aEnd, float aWidth,
|
||||
const BOARD_ITEM &aBoardItem );
|
||||
|
@ -83,15 +66,32 @@ public:
|
|||
bool Intersect( const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut ) const override;
|
||||
INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const override;
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
|
||||
private:
|
||||
RAYSEG2D m_segment;
|
||||
|
||||
SFVEC2F m_leftStart;
|
||||
SFVEC2F m_leftEnd;
|
||||
SFVEC2F m_leftEndMinusStart;
|
||||
SFVEC2F m_leftDir;
|
||||
|
||||
SFVEC2F m_rightStart;
|
||||
SFVEC2F m_rightEnd;
|
||||
SFVEC2F m_rightEndMinusStart;
|
||||
SFVEC2F m_rightDir;
|
||||
|
||||
float m_radius;
|
||||
float m_radius_squared;
|
||||
float m_width;
|
||||
};
|
||||
|
||||
static const float s_min_dot = (FLT_EPSILON * 4.0f * FLT_EPSILON * 4.0f) ;
|
||||
|
||||
/**
|
||||
* @brief Segment_is_a_circle - check if segment start and end is very close to each other
|
||||
* should used to check if the segment should be converted to a circle instead
|
||||
* @param aStart
|
||||
* @param aEnd
|
||||
* Check if segment start and end is very close to each other.
|
||||
*
|
||||
* This should used to check if the segment should be converted to a circle instead.
|
||||
*
|
||||
* @return true is it is better to convert the segment to circle
|
||||
*/
|
||||
inline bool Is_segment_a_circle( const SFVEC2F &aStart, const SFVEC2F &aEnd )
|
||||
|
@ -99,7 +99,7 @@ inline bool Is_segment_a_circle( const SFVEC2F &aStart, const SFVEC2F &aEnd )
|
|||
const SFVEC2F vec = aEnd - aStart;
|
||||
|
||||
return (aStart == aEnd) ||
|
||||
// This is the same as calc the lenght squared (without the sqrt)
|
||||
// This is the same as calc the length squared (without the sqrt)
|
||||
// and compare with a small value
|
||||
( glm::dot( vec, vec ) <= s_min_dot );
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -34,26 +34,26 @@
|
|||
#include <wx/debug.h>
|
||||
|
||||
#include <wx/glcanvas.h> // CALLBACK definition, needed on Windows
|
||||
// alse needed on OSX to define __DARWIN__
|
||||
// also needed on OSX to define __DARWIN__
|
||||
#include <geometry/polygon_triangulation.h>
|
||||
#include "../../../3d_fastmath.h"
|
||||
|
||||
|
||||
CTRIANGLE2D::CTRIANGLE2D(
|
||||
const SFVEC2F& aV1, const SFVEC2F& aV2, const SFVEC2F& aV3, const BOARD_ITEM& aBoardItem )
|
||||
: COBJECT2D( OBJECT2D_TYPE::TRIANGLE, aBoardItem )
|
||||
CTRIANGLE2D::CTRIANGLE2D( const SFVEC2F& aV1, const SFVEC2F& aV2, const SFVEC2F& aV3,
|
||||
const BOARD_ITEM& aBoardItem ) :
|
||||
COBJECT2D( OBJECT2D_TYPE::TRIANGLE, aBoardItem )
|
||||
{
|
||||
p1 = aV1;
|
||||
p2 = aV2;
|
||||
p3 = aV3;
|
||||
|
||||
// Pre-Calc values
|
||||
m_inv_denominator = 1.0f / ( (p2.y - p3.y) * (p1.x - p3.x) +
|
||||
(p3.x - p2.x) * (p1.y - p3.y));
|
||||
m_p2y_minus_p3y = (p2.y - p3.y);
|
||||
m_p3x_minus_p2x = (p3.x - p2.x);
|
||||
m_p3y_minus_p1y = (p3.y - p1.y);
|
||||
m_p1x_minus_p3x = (p1.x - p3.x);
|
||||
m_inv_denominator = 1.0f / ( ( p2.y - p3.y ) * ( p1.x - p3.x ) +
|
||||
( p3.x - p2.x ) * ( p1.y - p3.y ) );
|
||||
m_p2y_minus_p3y = ( p2.y - p3.y );
|
||||
m_p3x_minus_p2x = ( p3.x - p2.x );
|
||||
m_p3y_minus_p1y = ( p3.y - p1.y );
|
||||
m_p1x_minus_p3x = ( p1.x - p3.x );
|
||||
|
||||
m_bbox.Reset();
|
||||
m_bbox.Union( aV1 );
|
||||
|
@ -70,6 +70,7 @@ bool CTRIANGLE2D::Intersects( const CBBOX2D &aBBox ) const
|
|||
{
|
||||
if( !m_bbox.Intersects( aBBox ) )
|
||||
return false;
|
||||
|
||||
//!TODO: Optimize
|
||||
return true;
|
||||
}
|
||||
|
@ -94,6 +95,7 @@ INTERSECTION_RESULT CTRIANGLE2D::IsBBoxInside( const CBBOX2D &aBBox ) const
|
|||
{
|
||||
if( !m_bbox.Intersects( aBBox ) )
|
||||
return INTERSECTION_RESULT::MISSES;
|
||||
|
||||
// !TODO:
|
||||
return INTERSECTION_RESULT::MISSES;
|
||||
}
|
||||
|
@ -129,6 +131,9 @@ void Convert_shape_line_polygon_to_triangles( SHAPE_POLY_SET &aPolyList,
|
|||
float aBiuTo3DunitsScale ,
|
||||
const BOARD_ITEM &aBoardItem )
|
||||
{
|
||||
VECTOR2I a;
|
||||
VECTOR2I b;
|
||||
VECTOR2I c;
|
||||
|
||||
aPolyList.CacheTriangulation( false );
|
||||
const double conver_d = (double)aBiuTo3DunitsScale;
|
||||
|
@ -139,9 +144,6 @@ void Convert_shape_line_polygon_to_triangles( SHAPE_POLY_SET &aPolyList,
|
|||
|
||||
for( size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
|
||||
{
|
||||
VECTOR2I a;
|
||||
VECTOR2I b;
|
||||
VECTOR2I c;
|
||||
triPoly->GetTriangle( i, a, b, c );
|
||||
|
||||
aDstContainer.Add( new CTRIANGLE2D( SFVEC2F( a.x * conver_d,
|
||||
|
@ -152,6 +154,5 @@ void Convert_shape_line_polygon_to_triangles( SHAPE_POLY_SET &aPolyList,
|
|||
-c.y * conver_d ),
|
||||
aBoardItem ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -38,17 +38,6 @@
|
|||
|
||||
class CTRIANGLE2D : public COBJECT2D
|
||||
{
|
||||
private:
|
||||
SFVEC2F p1;
|
||||
SFVEC2F p2;
|
||||
SFVEC2F p3;
|
||||
|
||||
float m_inv_denominator;
|
||||
float m_p2y_minus_p3y;
|
||||
float m_p3x_minus_p2x;
|
||||
float m_p3y_minus_p1y;
|
||||
float m_p1x_minus_p3x;
|
||||
|
||||
public:
|
||||
CTRIANGLE2D ( const SFVEC2F &aV1,
|
||||
const SFVEC2F &aV2,
|
||||
|
@ -65,6 +54,17 @@ public:
|
|||
bool Intersect( const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut ) const override;
|
||||
INTERSECTION_RESULT IsBBoxInside( const CBBOX2D &aBBox ) const override;
|
||||
bool IsPointInside( const SFVEC2F &aPoint ) const override;
|
||||
|
||||
private:
|
||||
SFVEC2F p1;
|
||||
SFVEC2F p2;
|
||||
SFVEC2F p3;
|
||||
|
||||
float m_inv_denominator;
|
||||
float m_p2y_minus_p3y;
|
||||
float m_p3x_minus_p2x;
|
||||
float m_p3y_minus_p1y;
|
||||
float m_p1x_minus_p3x;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2017 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -105,12 +105,12 @@ void CBBOX::Reset()
|
|||
|
||||
void CBBOX::Union( const SFVEC3F &aPoint )
|
||||
{
|
||||
// get the minimun value between the added point and the existent bounding box
|
||||
// get the minimum value between the added point and the existent bounding box
|
||||
m_min.x = fminf( m_min.x, aPoint.x );
|
||||
m_min.y = fminf( m_min.y, aPoint.y );
|
||||
m_min.z = fminf( m_min.z, aPoint.z );
|
||||
|
||||
// get the maximun value between the added point and the existent bounding box
|
||||
// get the maximum value between the added point and the existent bounding box
|
||||
m_max.x = fmaxf( m_max.x, aPoint.x );
|
||||
m_max.y = fmaxf( m_max.y, aPoint.y );
|
||||
m_max.z = fmaxf( m_max.z, aPoint.z );
|
||||
|
@ -121,12 +121,12 @@ void CBBOX::Union( const CBBOX &aBBox )
|
|||
{
|
||||
wxASSERT( aBBox.IsInitialized() );
|
||||
|
||||
// get the minimun value between the added bounding box and the existent bounding box
|
||||
// get the minimum value between the added bounding box and the existent bounding box
|
||||
m_min.x = fmin( m_min.x, aBBox.m_min.x );
|
||||
m_min.y = fmin( m_min.y, aBBox.m_min.y );
|
||||
m_min.z = fmin( m_min.z, aBBox.m_min.z );
|
||||
|
||||
// get the maximun value between the added bounding box and the existent bounding box
|
||||
// get the maximum value between the added bounding box and the existent bounding box
|
||||
m_max.x = fmax( m_max.x, aBBox.m_max.x );
|
||||
m_max.y = fmax( m_max.y, aBBox.m_max.y );
|
||||
m_max.z = fmax( m_max.z, aBBox.m_max.z );
|
||||
|
@ -397,5 +397,5 @@ void CBBOX::ApplyTransformationAA( glm::mat4 aTransformMatrix )
|
|||
void CBBOX::debug() const
|
||||
{
|
||||
wxLogDebug( "min(%f, %f, %f) - max(%f, %f, %f)\n", m_min.x, m_min.y, m_min.z,
|
||||
m_max.x, m_max.y, m_max.z );
|
||||
m_max.x, m_max.y, m_max.z );
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -33,32 +33,28 @@
|
|||
#include "../ray.h"
|
||||
|
||||
/**
|
||||
* CBBOX
|
||||
* manages a bounding box defined by two SFVEC3F min max points.
|
||||
* Manage a bounding box defined by two SFVEC3F min max points.
|
||||
*/
|
||||
struct CBBOX
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor CBBOX
|
||||
* Create with default values a bounding box (not inizialized)
|
||||
* Create with default values a bounding box (not initialized)
|
||||
*/
|
||||
CBBOX();
|
||||
|
||||
/**
|
||||
* Constructor CBBOX
|
||||
* Initialize a bounding box with a given point
|
||||
* @param aPbInit a point for the bounding box initialization
|
||||
* Initialize a bounding box with a given point.
|
||||
*
|
||||
* @param aPbInit a point for the bounding box initialization.
|
||||
*/
|
||||
explicit CBBOX( const SFVEC3F &aPbInit );
|
||||
|
||||
/**
|
||||
* Constructor CBBOX
|
||||
* Initialize a bounding box with a minimon and a maximun point
|
||||
* @param aPbMin the minimun point to initialize the bounding box
|
||||
* @param aPbMax the maximun point to initialize the bounding box
|
||||
* Initialize a bounding box with a minimum and a maximum point.
|
||||
*
|
||||
* @param aPbMin the minimum point to initialize the bounding box.
|
||||
* @param aPbMax the maximum point to initialize the bounding box.
|
||||
*/
|
||||
CBBOX( const SFVEC3F &aPbMin, const SFVEC3F &aPbMax );
|
||||
|
||||
|
@ -66,10 +62,10 @@ public:
|
|||
|
||||
|
||||
/**
|
||||
* Function Set
|
||||
* Set bounding box with new parameters
|
||||
* @param aPbMin the minimun point to initialize the bounding box
|
||||
* @param aPbMax the maximun point to initialize the bounding box
|
||||
* Set bounding box with new parameters.
|
||||
*
|
||||
* @param aPbMin the minimum point to initialize the bounding box.
|
||||
* @param aPbMax the maximum point to initialize the bounding box.
|
||||
*/
|
||||
void Set( const SFVEC3F &aPbMin, const SFVEC3F &aPbMax );
|
||||
|
||||
|
@ -80,177 +76,166 @@ public:
|
|||
* @param aPbMin
|
||||
* @param aPbMax
|
||||
*/
|
||||
void Set( const SFVEC3F &aPoint );
|
||||
void Set( const SFVEC3F& aPoint );
|
||||
|
||||
/**
|
||||
* Function Union
|
||||
* recalculate the bounding box adding a point
|
||||
* @param aPoint the point to be bounded
|
||||
* Recalculate the bounding box adding a point.
|
||||
*
|
||||
* @param aPoint the point to be bounded.
|
||||
*/
|
||||
void Union( const SFVEC3F &aPoint );
|
||||
|
||||
/**
|
||||
* Function Union
|
||||
* recalculate the bounding box adding other bounding box
|
||||
* @param aBBox the bounding box to be bounded
|
||||
* Recalculate the bounding box adding other bounding box.
|
||||
*
|
||||
* @param aBBox the bounding box to be bounded.
|
||||
*/
|
||||
void Union( const CBBOX &aBBox );
|
||||
|
||||
/**
|
||||
* Function Scale
|
||||
* scales a bounding box by its center
|
||||
* @param aScale scale factor to apply
|
||||
* Scales a bounding box by its center.
|
||||
*
|
||||
* @param aScale scale factor to apply.
|
||||
*/
|
||||
void Scale( float aScale );
|
||||
|
||||
/**
|
||||
* Function ScaleNextUp
|
||||
* scales a bounding box to the next float representation making it larger
|
||||
* Scale a bounding box to the next float representation making it larger.
|
||||
*/
|
||||
void ScaleNextUp();
|
||||
|
||||
/**
|
||||
* Function ScaleNextDown
|
||||
* scales a bounding box to the next float representation making it smaller
|
||||
* Scale a bounding box to the next float representation making it smaller.
|
||||
*/
|
||||
void ScaleNextDown();
|
||||
|
||||
/**
|
||||
* Function Intersects
|
||||
* test if a bounding box intersects this box
|
||||
* @param aBBox the bounding box to check if it intersects
|
||||
* Test if a bounding box intersects this box.
|
||||
*
|
||||
* @param aBBox the bounding box to check if it intersects.
|
||||
*/
|
||||
bool Intersects( const CBBOX &aBBox ) const;
|
||||
|
||||
/**
|
||||
* Function Inside
|
||||
* check is a point is inside this bounding box
|
||||
* @param aPoint point to test
|
||||
* Check if a point is inside this bounding box.
|
||||
*
|
||||
* @param aPoint point to test.
|
||||
*/
|
||||
bool Inside( const SFVEC3F &aPoint ) const;
|
||||
|
||||
/**
|
||||
* Function ApplyTransformation
|
||||
* apply a transformation matrix to the box points
|
||||
* Apply a transformation matrix to the box points.
|
||||
*
|
||||
* @param aTransformMatrix matrix to apply to the points of the bounding box
|
||||
*/
|
||||
void ApplyTransformation( glm::mat4 aTransformMatrix );
|
||||
|
||||
/**
|
||||
* Function ApplyTransformationAA
|
||||
* apply a transformation matrix to the box points and recalculate it
|
||||
* to fit an axis aligned bounding box
|
||||
* @param aTransformMatrix matrix to apply to the points of the bounding box
|
||||
* Apply a transformation matrix to the box points and recalculate it
|
||||
* to fit an axis aligned bounding box.
|
||||
*
|
||||
* @param aTransformMatrix matrix to apply to the points of the bounding box.
|
||||
*/
|
||||
void ApplyTransformationAA( glm::mat4 aTransformMatrix );
|
||||
|
||||
/**
|
||||
* Function Volume
|
||||
* calculate the volume of a bounding box
|
||||
* @return float - volume of this bounding box
|
||||
* Calculate the volume of a bounding box.
|
||||
*
|
||||
* @return float - volume of this bounding box.
|
||||
*/
|
||||
float Volume() const;
|
||||
|
||||
/**
|
||||
* Function debug
|
||||
* output to stdout
|
||||
* Output this CBBOX to the stdout.
|
||||
*/
|
||||
void debug() const;
|
||||
|
||||
/**
|
||||
* Function IsInitialized
|
||||
* check if this bounding box is already initialized
|
||||
* @return bool - return true if it was initialized, false if otherwise
|
||||
* Check if this bounding box is already initialized.
|
||||
*
|
||||
* @return bool - return true if it was initialized, false if otherwise.
|
||||
*/
|
||||
bool IsInitialized() const;
|
||||
|
||||
/**
|
||||
* Function Reset
|
||||
* reset the bounding box to zero and de-initialized it
|
||||
* Reset the bounding box to zero and de-initialized it.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* Function GetCenter
|
||||
* return the center point of the bounding box
|
||||
* @return SFVEC3F - the position of the center of this bounding box
|
||||
* Return the center point of the bounding box.
|
||||
*
|
||||
* @return SFVEC3F - the position of the center of this bounding box.
|
||||
*/
|
||||
SFVEC3F GetCenter() const;
|
||||
|
||||
/**
|
||||
* Function GetCenter
|
||||
* return the center point of the bounding box for one Axis (0, 1 or 2)
|
||||
* Return the center point of the bounding box for one axis (0, 1 or 2).
|
||||
*
|
||||
* @return float - the position of the center of this bounding box for the axis
|
||||
*/
|
||||
float GetCenter( unsigned int aAxis ) const;
|
||||
|
||||
/** Function Offset
|
||||
*
|
||||
* @return SFVEC3F - return the offset relative to max-min
|
||||
/**
|
||||
* @return SFVEC3F - return the offset relative to max-min.
|
||||
*/
|
||||
SFVEC3F Offset( const SFVEC3F &p ) const;
|
||||
|
||||
/**
|
||||
* Function GetExtent
|
||||
* @return SFVEC3F - max-min
|
||||
* @return SFVEC3F - max-min.
|
||||
*/
|
||||
const SFVEC3F GetExtent() const;
|
||||
|
||||
/**
|
||||
* Function Min
|
||||
* return the minimun vertex pointer
|
||||
* @return SFVEC3F - the minimun vertice position
|
||||
* Return the minimum vertex pointer.
|
||||
*
|
||||
* @return SFVEC3F - the minimum vertex position.
|
||||
*/
|
||||
const SFVEC3F &Min() const { return m_min; }
|
||||
|
||||
/**
|
||||
* Function Max
|
||||
* return the maximum vertex pointer
|
||||
* @return SFVEC3F - the maximun vertice position
|
||||
* Return the maximum vertex pointer.
|
||||
*
|
||||
* @return SFVEC3F - the maximum vertex position.
|
||||
*/
|
||||
const SFVEC3F &Max() const { return m_max; }
|
||||
|
||||
|
||||
/**
|
||||
* Function MaxDimension
|
||||
* @return the index of the max dimention (0=x, 1=y, 2=z)
|
||||
* @return the index of the max dimension (0=x, 1=y, 2=z).
|
||||
*/
|
||||
unsigned int MaxDimension() const;
|
||||
|
||||
/**
|
||||
* @brief GetMaxDimension
|
||||
* @return the max dimension
|
||||
* @return the max dimension.
|
||||
*/
|
||||
float GetMaxDimension() const;
|
||||
|
||||
/**
|
||||
* Function SurfaceArea
|
||||
* @return the surface are of the box
|
||||
* @return the surface are of the box.
|
||||
*/
|
||||
float SurfaceArea() const;
|
||||
|
||||
/**
|
||||
* Function Intersect
|
||||
* @param aRay = ray to intersect the box
|
||||
* @param t = distance point of the ray of the intersection (if true)
|
||||
* @return true if the ray hits the box
|
||||
* @param aRay The ray to intersect the box.
|
||||
* @param t The distance point of the ray of the intersection (if true).
|
||||
* @return true if the ray hits the box.
|
||||
*/
|
||||
bool Intersect( const RAY &aRay, float *t ) const;
|
||||
|
||||
bool Intersect( const RAY &aRay ) const;
|
||||
|
||||
/**
|
||||
* Function Intersect - Useful for get the enter and exit position
|
||||
* If the ray starts inside the bbox, it will return aOutHitt0 = 0.0
|
||||
* @param aRay = ray to intersect the box
|
||||
* @param aOutHitt0 = distance point of the ray of the intersection (if true)
|
||||
* @param aOutHitt1 = distance point of the ray of the exit (if true)
|
||||
* Fetch the enter and exit position when a ray starts inside the bounding box.
|
||||
*
|
||||
* @param aRay The ray to intersect the box.
|
||||
* @param aOutHitt0 The distance point of the ray of the intersection (if true).
|
||||
* @param aOutHitt1 The distance point of the ray of the exit (if true).
|
||||
* @return true if the ray hits the box
|
||||
*/
|
||||
bool Intersect( const RAY &aRay, float *aOutHitt0, float *aOutHitt1 ) const;
|
||||
|
||||
private:
|
||||
|
||||
SFVEC3F m_min; ///< (12) point of the lower position of the bounding box
|
||||
SFVEC3F m_max; ///< (12) point of the higher position of the bounding box
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -180,6 +180,7 @@ bool CVCYLINDER::Intersects( const CBBOX &aBBox ) const
|
|||
return m_bbox.Intersects( aBBox );
|
||||
}
|
||||
|
||||
|
||||
SFVEC3F CVCYLINDER::GetDiffuseColor( const HITINFO &aHitInfo ) const
|
||||
{
|
||||
(void)aHitInfo; // unused
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -40,7 +40,6 @@ class CVCYLINDER : public COBJECT
|
|||
|
||||
public:
|
||||
/**
|
||||
* Constructor CVCYLINDER
|
||||
* @param aCenterPoint = position of the vertical cylinder axis in the XY plane
|
||||
* @param aZmin = bottom position (Z axis)
|
||||
* @param aZmax = top position (Z axis)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -33,22 +33,22 @@
|
|||
#include "cobject.h"
|
||||
|
||||
/**
|
||||
* A dummy block is used to fill the polygons. It will only will be intersepted
|
||||
* from top or from bottom
|
||||
* A dummy block is used to fill the polygons. It will only will be intercepted
|
||||
* from top or from bottom.
|
||||
*/
|
||||
class CDUMMYBLOCK : public COBJECT
|
||||
{
|
||||
|
||||
public:
|
||||
explicit CDUMMYBLOCK( const CBBOX &aBBox );
|
||||
|
||||
void SetColor( SFVEC3F aObjColor ) { m_diffusecolor = aObjColor; }
|
||||
|
||||
// Imported from COBJECT
|
||||
// Imported from COBJECT
|
||||
bool Intersect( const RAY &aRay, HITINFO &aHitInfo ) const override;
|
||||
bool IntersectP(const RAY &aRay , float aMaxDistance ) const override;
|
||||
bool Intersects( const CBBOX &aBBox ) const override;
|
||||
SFVEC3F GetDiffuseColor( const HITINFO &aHitInfo ) const override;
|
||||
|
||||
private:
|
||||
SFVEC3F m_diffusecolor;
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -199,13 +199,12 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
|
|||
else
|
||||
{
|
||||
// At this point, the ray miss the two planes but it still
|
||||
// hits the box. It means that the rays are "(almost)paralell"
|
||||
// hits the box. It means that the rays are "(almost)parallel"
|
||||
// to the planes, so must calc the intersection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SFVEC3F boxHitPointStart = aRay.at( tBBoxStart );
|
||||
SFVEC3F boxHitPointEnd = aRay.at( tBBoxEnd );
|
||||
|
||||
|
@ -431,7 +430,7 @@ bool CLAYERITEM::IntersectP( const RAY &aRay , float aMaxDistance ) const
|
|||
else
|
||||
{
|
||||
// At this point, the ray miss the two planes but it still
|
||||
// hits the box. It means that the rays are "(almost)paralell"
|
||||
// hits the box. It means that the rays are "(almost)parallel"
|
||||
// to the planes, so must calc the intersection
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -36,11 +36,7 @@
|
|||
|
||||
class CLAYERITEM : public COBJECT
|
||||
{
|
||||
protected:
|
||||
const COBJECT2D *m_object2d;
|
||||
|
||||
public:
|
||||
|
||||
CLAYERITEM( const COBJECT2D *aObject2D, float aZMin, float aZMax );
|
||||
|
||||
void SetColor( SFVEC3F aObjColor ) { m_diffusecolor = aObjColor; }
|
||||
|
@ -51,6 +47,9 @@ public:
|
|||
bool Intersects( const CBBOX &aBBox ) const override;
|
||||
SFVEC3F GetDiffuseColor( const HITINFO &aHitInfo ) const override;
|
||||
|
||||
protected:
|
||||
const COBJECT2D *m_object2d;
|
||||
|
||||
private:
|
||||
SFVEC3F m_diffusecolor;
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@ COBJECT3D_STATS *COBJECT3D_STATS::s_instance = 0;
|
|||
|
||||
static const CBLINN_PHONG_MATERIAL s_defaultMaterial = CBLINN_PHONG_MATERIAL();
|
||||
|
||||
|
||||
COBJECT::COBJECT( OBJECT3D_TYPE aObjType )
|
||||
{
|
||||
m_obj_type = aObjType;
|
||||
|
@ -69,6 +70,6 @@ void COBJECT3D_STATS::PrintStats()
|
|||
for( auto& objectType : objectTypeNames )
|
||||
{
|
||||
wxLogDebug( " %20s %u\n", objectType.second,
|
||||
m_counter[static_cast<int>( objectType.first )] );
|
||||
m_counter[static_cast<int>( objectType.first )] );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,22 +48,9 @@ enum class OBJECT3D_TYPE
|
|||
};
|
||||
|
||||
|
||||
class COBJECT
|
||||
class COBJECT
|
||||
{
|
||||
protected:
|
||||
CBBOX m_bbox;
|
||||
SFVEC3F m_centroid;
|
||||
OBJECT3D_TYPE m_obj_type;
|
||||
const CMATERIAL *m_material;
|
||||
|
||||
BOARD_ITEM *m_boardItem;
|
||||
|
||||
// m_modelTransparency combines the material and model opacity
|
||||
// 0.0 full opaque, 1.0 full transparent.
|
||||
float m_modelTransparency;
|
||||
|
||||
public:
|
||||
|
||||
explicit COBJECT( OBJECT3D_TYPE aObjType );
|
||||
|
||||
const void SetBoardItem( BOARD_ITEM *aBoardItem ) { m_boardItem = aBoardItem; }
|
||||
|
@ -77,32 +64,29 @@ public:
|
|||
|
||||
const CMATERIAL *GetMaterial() const { return m_material; }
|
||||
float GetModelTransparency() const { return m_modelTransparency; }
|
||||
void SetModelTransparency( float aModelTransparency ) { m_modelTransparency = aModelTransparency; }
|
||||
void SetModelTransparency( float aModelTransparency )
|
||||
{
|
||||
m_modelTransparency = aModelTransparency;
|
||||
}
|
||||
|
||||
virtual SFVEC3F GetDiffuseColor( const HITINFO &aHitInfo ) const = 0;
|
||||
|
||||
virtual ~COBJECT() {}
|
||||
|
||||
/** Function Intersects
|
||||
* @brief Intersects - a.Intersects(b) ⇔ !a.Disjoint(b) ⇔ !(a ∩ b = ∅)
|
||||
/**
|
||||
* Intersects - a.Intersects(b) ⇔ !a.Disjoint(b) ⇔ !(a ∩ b = ∅).
|
||||
*
|
||||
* It intersects if the result intersection is not null
|
||||
* @param aBBox
|
||||
* @return
|
||||
*/
|
||||
virtual bool Intersects( const CBBOX &aBBox ) const = 0;
|
||||
|
||||
|
||||
/** Functions Intersect
|
||||
* @brief Intersect
|
||||
* @param aRay
|
||||
* @param aHitInfo
|
||||
/**
|
||||
* @return true if the aRay intersects the object
|
||||
*/
|
||||
virtual bool Intersect( const RAY &aRay, HITINFO &aHitInfo ) const = 0;
|
||||
|
||||
/** Functions Intersect for shadow test
|
||||
* @brief Intersect
|
||||
* @param aRay
|
||||
/**
|
||||
* @param aMaxDistance - max distance of the test
|
||||
* @return true if the aRay intersects the object
|
||||
*/
|
||||
|
@ -111,6 +95,18 @@ public:
|
|||
const CBBOX &GetBBox() const { return m_bbox; }
|
||||
|
||||
const SFVEC3F &GetCentroid() const { return m_centroid; }
|
||||
|
||||
protected:
|
||||
CBBOX m_bbox;
|
||||
SFVEC3F m_centroid;
|
||||
OBJECT3D_TYPE m_obj_type;
|
||||
const CMATERIAL *m_material;
|
||||
|
||||
BOARD_ITEM *m_boardItem;
|
||||
|
||||
// m_modelTransparency combines the material and model opacity
|
||||
// 0.0 full opaque, 1.0 full transparent.
|
||||
float m_modelTransparency;
|
||||
};
|
||||
|
||||
|
||||
|
@ -148,9 +144,8 @@ private:
|
|||
COBJECT3D_STATS(){ ResetStats(); }
|
||||
COBJECT3D_STATS( const COBJECT3D_STATS &old );
|
||||
const COBJECT3D_STATS &operator=( const COBJECT3D_STATS &old );
|
||||
~COBJECT3D_STATS(){}
|
||||
~COBJECT3D_STATS() {}
|
||||
|
||||
private:
|
||||
unsigned int m_counter[static_cast<int>( OBJECT3D_TYPE::MAX )];
|
||||
|
||||
static COBJECT3D_STATS *s_instance;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -37,12 +37,10 @@
|
|||
*/
|
||||
class CXYPLANE : public COBJECT
|
||||
{
|
||||
|
||||
public:
|
||||
explicit CXYPLANE( const CBBOX &aBBox );
|
||||
|
||||
/**
|
||||
* Constructor CXYPLANE
|
||||
* @param aCenterPoint = position of the center of the plane
|
||||
* @param aXSize = size by X axis
|
||||
* @param aYSize = size by Y axis
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "croundseg.h"
|
||||
|
||||
|
||||
CROUNDSEG::CROUNDSEG( const CROUNDSEGMENT2D& aSeg2D, float aZmin, float aZmax )
|
||||
: COBJECT( OBJECT3D_TYPE::ROUNDSEG ), m_segment( aSeg2D.m_segment )
|
||||
{
|
||||
|
@ -60,7 +61,7 @@ CROUNDSEG::CROUNDSEG( const CROUNDSEGMENT2D& aSeg2D, float aZmin, float aZmax )
|
|||
|
||||
bool CROUNDSEG::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
|
||||
{
|
||||
// Top / Botton plane
|
||||
// Top / Bottom plane
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
float zPlanePos = aRay.m_dirIsNeg[2]? m_bbox.Max().z : m_bbox.Min().z;
|
||||
|
||||
|
@ -279,7 +280,7 @@ bool CROUNDSEG::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
|
|||
|
||||
bool CROUNDSEG::IntersectP( const RAY &aRay, float aMaxDistance ) const
|
||||
{
|
||||
// Top / Botton plane
|
||||
// Top / Bottom plane
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
const float zPlanePos = aRay.m_dirIsNeg[2]? m_bbox.Max().z : m_bbox.Min().z;
|
||||
|
||||
|
@ -434,7 +435,7 @@ bool CROUNDSEG::IntersectP( const RAY &aRay, float aMaxDistance ) const
|
|||
|
||||
bool CROUNDSEG::Intersects( const CBBOX &aBBox ) const
|
||||
{
|
||||
//!TODO: improove
|
||||
//!TODO: improve
|
||||
return m_bbox.Intersects( aBBox );
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -33,16 +33,9 @@
|
|||
#include "cobject.h"
|
||||
#include "../shapes2D/croundsegment2d.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class CROUNDSEG : public COBJECT
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor CROUNDSEG
|
||||
*/
|
||||
CROUNDSEG( const CROUNDSEGMENT2D &aSeg2D, float aZmin, float aZmax );
|
||||
|
||||
void SetColor( SFVEC3F aObjColor ) { m_diffusecolor = aObjColor; }
|
||||
|
@ -69,6 +62,7 @@ private:
|
|||
SFVEC3F m_diffusecolor;
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* This is a object similar to a round segment but with a ring
|
||||
|
@ -77,9 +71,6 @@ private:
|
|||
class COBLONGRING : public COBJECT
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor CROUNDSEG
|
||||
*/
|
||||
CROUNDSEG( const SFVEC2F &aStart,
|
||||
const SFVEC2F &aEnd,
|
||||
float aInnerRadius,
|
||||
|
@ -109,4 +100,5 @@ private:
|
|||
float m_seglen_over_two_squared;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // _CROUNDSEG_H_
|
||||
|
|
|
@ -39,16 +39,15 @@
|
|||
/**
|
||||
* A triangle object
|
||||
*/
|
||||
class CTRIANGLE : public COBJECT
|
||||
class CTRIANGLE : public COBJECT
|
||||
{
|
||||
|
||||
public:
|
||||
CTRIANGLE( const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3 );
|
||||
|
||||
CTRIANGLE( const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3,
|
||||
const SFVEC3F &aFaceNormal );
|
||||
|
||||
CTRIANGLE( const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3,
|
||||
CTRIANGLE( const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3,
|
||||
const SFVEC3F &aN1, const SFVEC3F &aN2, const SFVEC3F &aN3 );
|
||||
|
||||
void SetColor( const SFVEC3F &aColor );
|
||||
|
@ -72,7 +71,6 @@ public:
|
|||
private:
|
||||
void pre_calc_const();
|
||||
|
||||
private:
|
||||
SFVEC3F m_normal[3]; // 36
|
||||
SFVEC3F m_vertex[3]; // 36
|
||||
SFVEC3F m_n; // 12
|
||||
|
|
Loading…
Reference in New Issue