3D viewer code cleaning round 1.

This commit is contained in:
Wayne Stambaugh 2020-12-11 08:51:42 -05:00
parent 7cb2d19814
commit d1fe4a0c98
31 changed files with 919 additions and 1086 deletions

View File

@ -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 );

View File

@ -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;

View File

@ -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;
};

View File

@ -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 )

View File

@ -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_

View File

@ -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 )] );
}
}

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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 );
}
}
}

View File

@ -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];
};

View File

@ -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;

View File

@ -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;
};

View File

@ -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

View File

@ -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 );
}

View File

@ -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 ) );
}
}
}

View File

@ -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;
};

View File

@ -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 );
}

View File

@ -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
};

View File

@ -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

View File

@ -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)

View File

@ -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;
};

View File

@ -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
}
}

View File

@ -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;
};

View File

@ -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 )] );
}
}

View File

@ -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;

View File

@ -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

View File

@ -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 );
}

View File

@ -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_

View File

@ -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