3d-viewer: fixes and enhancements.
This commit is contained in:
parent
5c26381963
commit
d80a3d651e
|
@ -196,13 +196,13 @@ private:
|
|||
* Helper function SetGLEpoxyColor
|
||||
* Initialize the color to draw the epoxy body board in realistic mode.
|
||||
*/
|
||||
void setGLEpoxyColor( double aTransparency = 1.0 );
|
||||
void setGLEpoxyColor( float aTransparency = 1.0 );
|
||||
|
||||
/**
|
||||
* Helper function SetGLSolderMaskColor
|
||||
* Initialize the color to draw the solder mask layers in realistic mode.
|
||||
*/
|
||||
void setGLSolderMaskColor( double aTransparency = 1.0 );
|
||||
void setGLSolderMaskColor( float aTransparency = 1.0 );
|
||||
|
||||
/**
|
||||
* Function BuildBoard3DView
|
||||
|
|
|
@ -53,6 +53,10 @@
|
|||
#include <trackball.h>
|
||||
#include <3d_draw_basic_functions.h>
|
||||
|
||||
#include <CImage.h>
|
||||
|
||||
|
||||
|
||||
/* returns the Z orientation parameter 1.0 or -1.0 for aLayer
|
||||
* Z orientation is 1.0 for all layers but "back" layers:
|
||||
* B_Cu , B_Adhes, B_Paste ), B_SilkS
|
||||
|
@ -61,99 +65,14 @@
|
|||
static GLfloat Get3DLayer_Z_Orientation( LAYER_NUM aLayer );
|
||||
|
||||
|
||||
/* Based on the tutorial http://www.ulrichmierendorff.com/software/opengl_blur.html
|
||||
* It will blur a openGL texture
|
||||
*/
|
||||
static void blur_tex( GLuint aTex, int aPasses, GLuint aTexture_size )
|
||||
{
|
||||
int i, x, y;
|
||||
|
||||
glFlush();
|
||||
glFinish();
|
||||
|
||||
glPushAttrib( GL_ALL_ATTRIB_BITS );
|
||||
|
||||
glDisable( GL_LIGHTING );
|
||||
|
||||
glDisable( GL_CULL_FACE );
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_ALPHA_TEST );
|
||||
glDisable( GL_COLOR_MATERIAL );
|
||||
|
||||
glReadBuffer( GL_BACK_LEFT );
|
||||
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
||||
|
||||
|
||||
glViewport( 0, 0, aTexture_size, aTexture_size );
|
||||
|
||||
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glOrtho( 0.0f, aTexture_size, aTexture_size, 0.0f, -1.0f, 1.0f );
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glBindTexture( GL_TEXTURE_2D, aTex );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
|
||||
while (aPasses > 0)
|
||||
{
|
||||
i = 0;
|
||||
for (x = 0; x < 2; x++)
|
||||
{
|
||||
for (y = 0; y < 2; y++, i++)
|
||||
{
|
||||
glColor4f (1.0f,1.0f,1.0f,1.0 / (i + 1.0));
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f( 0 + (x - 0.5)/aTexture_size, 1 + (y-0.5)/aTexture_size );
|
||||
glVertex2f( 0, 0 );
|
||||
glTexCoord2f( 0 + (x - 0.5)/aTexture_size, 0 + (y-0.5)/aTexture_size );
|
||||
glVertex2f( 0, aTexture_size );
|
||||
glTexCoord2f( 1 + (x - 0.5)/aTexture_size, 1 + (y-0.5)/aTexture_size );
|
||||
glVertex2f( aTexture_size, 0 );
|
||||
glTexCoord2f( 1 + (x - 0.5)/aTexture_size, 0 + (y-0.5)/aTexture_size );
|
||||
glVertex2f( aTexture_size, aTexture_size );
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, aTexture_size, aTexture_size, 0 );
|
||||
aPasses--;
|
||||
}
|
||||
|
||||
glFlush();
|
||||
glFinish();
|
||||
glDisable( GL_BLEND );
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPopMatrix();
|
||||
|
||||
glPopAttrib();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::Create_and_Render_Shadow_Buffer( GLuint *aDst_gl_texture,
|
||||
GLuint aTexture_size, bool aDraw_body, int aBlurPasses )
|
||||
{
|
||||
|
||||
float *depthbufferFloat = (float*) malloc( aTexture_size * aTexture_size * sizeof(float) );
|
||||
unsigned char *depthbufferRGBA = (unsigned char*) malloc( aTexture_size * aTexture_size * 4 );
|
||||
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
|
||||
glViewport( 0, 0, aTexture_size, aTexture_size );
|
||||
glViewport( 0, 0, aTexture_size, aTexture_size);
|
||||
|
||||
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
@ -163,79 +82,70 @@ void EDA_3D_CANVAS::Create_and_Render_Shadow_Buffer( GLuint *aDst_gl_texture,
|
|||
-GetPrm3DVisu().m_BoardPos.y * GetPrm3DVisu().m_BiuTo3Dunits,
|
||||
0.0F );
|
||||
|
||||
if( aDraw_body )
|
||||
{
|
||||
if( m_glLists[GL_ID_BODY] )
|
||||
{
|
||||
if( aDraw_body && m_glLists[GL_ID_BODY] )
|
||||
glCallList( m_glLists[GL_ID_BODY] );
|
||||
}
|
||||
}
|
||||
|
||||
// Call model list
|
||||
glCallList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] );
|
||||
|
||||
if( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
|
||||
{
|
||||
glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] );
|
||||
}
|
||||
|
||||
glPixelStorei( GL_PACK_ALIGNMENT, 4 );
|
||||
glReadBuffer( GL_BACK_LEFT );
|
||||
if( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] )
|
||||
glCallList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] );
|
||||
|
||||
glFinish();
|
||||
|
||||
float *depthbufferFloat = (float*) malloc( aTexture_size * aTexture_size * sizeof(float) );
|
||||
for( unsigned int i = 0; i < (aTexture_size * aTexture_size); i++ )
|
||||
depthbufferFloat[i] = 1.0f;
|
||||
|
||||
glPixelStorei( GL_PACK_ALIGNMENT, 4 );
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
|
||||
glReadBuffer( GL_BACK_LEFT );
|
||||
glReadPixels( 0, 0,
|
||||
aTexture_size, aTexture_size,
|
||||
GL_DEPTH_COMPONENT, GL_FLOAT, depthbufferFloat );
|
||||
|
||||
|
||||
glFinish();
|
||||
|
||||
for( unsigned int i = 0; i< (aTexture_size * aTexture_size); i++ )
|
||||
{
|
||||
unsigned char v = depthbufferFloat[i] * 255;
|
||||
depthbufferRGBA[i * 4 + 0] = v;
|
||||
depthbufferRGBA[i * 4 + 1] = v;
|
||||
depthbufferRGBA[i * 4 + 2] = v;
|
||||
depthbufferRGBA[i * 4 + 3] = 255;
|
||||
}
|
||||
|
||||
glFinish();
|
||||
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glGenTextures( 1, aDst_gl_texture );
|
||||
glBindTexture( GL_TEXTURE_2D, *aDst_gl_texture );
|
||||
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
|
||||
CIMAGE imgDepthBuffer( aTexture_size, aTexture_size );
|
||||
CIMAGE imgDepthBufferAux( aTexture_size, aTexture_size );
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
imgDepthBuffer.setPixelsFromNormalizedFloat( depthbufferFloat );
|
||||
|
||||
free( depthbufferFloat );
|
||||
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aTexture_size, aTexture_size, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, depthbufferRGBA );
|
||||
wxString filename;
|
||||
//filename.Printf( "imgDepthBuffer_%04d", *aDst_gl_texture );
|
||||
//imgDepthBuffer.saveAsPNG( filename );
|
||||
|
||||
glFlush();
|
||||
glFinish();
|
||||
|
||||
CheckGLError( __FILE__, __LINE__ );
|
||||
|
||||
blur_tex( *aDst_gl_texture, aBlurPasses, aTexture_size );
|
||||
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
glBindTexture( GL_TEXTURE_2D, *aDst_gl_texture );
|
||||
|
||||
glGetTexImage( GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, depthbufferRGBA );
|
||||
|
||||
for(unsigned int i = 0; i< (aTexture_size * aTexture_size); i++)
|
||||
while (aBlurPasses > 0)
|
||||
{
|
||||
aBlurPasses--;
|
||||
imgDepthBufferAux.efxFilter( &imgDepthBuffer, 1.0, FILTER_BLUR);
|
||||
imgDepthBuffer.efxFilter( &imgDepthBufferAux, 1.0, FILTER_BLUR);
|
||||
}
|
||||
//filename.Printf( "imgDepthBuffer_blur_%04d", *aDst_gl_texture );
|
||||
//imgDepthBuffer.saveAsPNG( filename );
|
||||
|
||||
imgDepthBuffer.copyFull( &imgDepthBuffer, &imgDepthBuffer, COPY_MUL );
|
||||
//imgDepthBuffer.copyFull( &imgDepthBuffer, &imgDepthBuffer, COPY_MUL );
|
||||
//filename.Printf( "imgDepthBuffer_mul_%04d", *aDst_gl_texture );
|
||||
//imgDepthBuffer.saveAsPNG( filename );
|
||||
|
||||
//imgDepthBufferAux.efxFilter( &imgDepthBuffer, 1.0, FILTER_BLUR);
|
||||
//imgDepthBuffer.efxFilter( &imgDepthBufferAux, 1.0, FILTER_BLUR);
|
||||
//filename.Printf( "imgDepthBuffer_mulblur_%04d", *aDst_gl_texture );
|
||||
//imgDepthBuffer.saveAsPNG( filename );
|
||||
|
||||
imgDepthBuffer.invert();
|
||||
//filename.Printf( "imgDepthBuffer_invert_%04d", *aDst_gl_texture );
|
||||
//imgDepthBuffer.saveAsPNG( filename );
|
||||
|
||||
for(unsigned int i = 0; i < (aTexture_size * aTexture_size); i++)
|
||||
{
|
||||
float v = (float)depthbufferRGBA[i * 4] / 255.0f;
|
||||
v = v * v;
|
||||
depthbufferRGBA[i * 4 + 0] = 0;
|
||||
depthbufferRGBA[i * 4 + 1] = 0;
|
||||
depthbufferRGBA[i * 4 + 2] = 0;
|
||||
depthbufferRGBA[i * 4 + 3] = 255 - (unsigned char)(v * 255);
|
||||
depthbufferRGBA[i * 4 + 3] = imgDepthBuffer.m_pixels[i];
|
||||
}
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||
|
@ -246,7 +156,6 @@ void EDA_3D_CANVAS::Create_and_Render_Shadow_Buffer( GLuint *aDst_gl_texture,
|
|||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aTexture_size, aTexture_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, depthbufferRGBA );
|
||||
|
||||
free( depthbufferRGBA );
|
||||
free( depthbufferFloat );
|
||||
}
|
||||
|
||||
#define SHADOW_BOARD_SCALE 1.5f
|
||||
|
@ -281,7 +190,7 @@ void EDA_3D_CANVAS::GenerateFakeShadowsTextures()
|
|||
glTranslatef( 0, 0, 0.03 );
|
||||
glRotatef( 180, 0.0, 1.0, 0.0 );
|
||||
|
||||
Create_and_Render_Shadow_Buffer( &m_text_fake_shadow_front, 512, false, 5 );
|
||||
Create_and_Render_Shadow_Buffer( &m_text_fake_shadow_front, 512, false, 1 );
|
||||
|
||||
|
||||
// Render BACK shadow
|
||||
|
@ -290,7 +199,7 @@ void EDA_3D_CANVAS::GenerateFakeShadowsTextures()
|
|||
glTranslatef( 0, 0, 0.03 );
|
||||
///glRotatef( 0.0, 0.0, 1.0, 0.0 );
|
||||
|
||||
Create_and_Render_Shadow_Buffer( &m_text_fake_shadow_back, 512, false, 5 );
|
||||
Create_and_Render_Shadow_Buffer( &m_text_fake_shadow_back, 512, false, 1 );
|
||||
|
||||
// Render ALL BOARD shadow
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
|
@ -306,7 +215,7 @@ void EDA_3D_CANVAS::GenerateFakeShadowsTextures()
|
|||
glTranslatef( 0, 0, -0.4f );
|
||||
glRotatef( 180.0, 0.0, 1.0, 0.0 );
|
||||
|
||||
Create_and_Render_Shadow_Buffer( &m_text_fake_shadow_board, 512, true, 20 );
|
||||
Create_and_Render_Shadow_Buffer( &m_text_fake_shadow_board, 512, true, 5 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -451,16 +360,6 @@ void EDA_3D_CANVAS::Redraw()
|
|||
|
||||
if( isEnabled( FL_SHOW_BOARD_BODY ) )
|
||||
{
|
||||
if( !isEnabled( FL_RENDER_TEXTURES ) ||
|
||||
isEnabled( FL_SOLDERMASK ) || !isRealisticMode() )
|
||||
{
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
glDisable( GL_LIGHTING );
|
||||
|
||||
if( m_glLists[GL_ID_BODY] )
|
||||
|
@ -481,24 +380,22 @@ void EDA_3D_CANVAS::Redraw()
|
|||
glMateriali ( GL_FRONT_AND_BACK, GL_SHININESS, shininess_value );
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.x );
|
||||
|
||||
if( isRealisticMode() && isEnabled( FL_RENDER_TEXTURES ) )
|
||||
{
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
if( m_glLists[GL_ID_BOARD] )
|
||||
{
|
||||
glCallList( m_glLists[GL_ID_BOARD] );
|
||||
}
|
||||
|
||||
if( isRealisticMode() && isEnabled( FL_RENDER_TEXTURES ) )
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
else
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
|
||||
SetOpenGlDefaultMaterial();
|
||||
|
||||
if( m_glLists[GL_ID_TECH_LAYERS] )
|
||||
{
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glCallList( m_glLists[GL_ID_TECH_LAYERS] );
|
||||
}
|
||||
|
||||
|
@ -565,20 +462,15 @@ void EDA_3D_CANVAS::Redraw()
|
|||
if( isEnabled( FL_GRID ) && m_glLists[GL_ID_GRID] )
|
||||
glCallList( m_glLists[GL_ID_GRID] );
|
||||
|
||||
// This list must be drawn last, because it contains the
|
||||
// transparent gl objects, which should be drawn after all
|
||||
// non transparent objects
|
||||
if( isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
|
||||
glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] );
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
|
||||
// Draw Board Shadow
|
||||
if( isEnabled( FL_MODULE ) && isRealisticMode() &&
|
||||
isEnabled( FL_RENDER_SHADOWS ) )
|
||||
{
|
||||
if( m_glLists[GL_ID_SHADOW_BOARD] )
|
||||
{
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
glEnable( GL_CULL_FACE );
|
||||
glDisable( GL_COLOR_MATERIAL );
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
|
@ -588,6 +480,17 @@ void EDA_3D_CANVAS::Redraw()
|
|||
}
|
||||
}
|
||||
|
||||
// This list must be drawn last, because it contains the
|
||||
// transparent gl objects, which should be drawn after all
|
||||
// non transparent objects
|
||||
if( isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
|
||||
{
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] );
|
||||
}
|
||||
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
|
@ -1153,7 +1056,11 @@ void EDA_3D_CANVAS::BuildTechLayers3DView()
|
|||
currLayerPolyset += polyset;
|
||||
}
|
||||
|
||||
int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
|
||||
int thickness = 0;
|
||||
|
||||
if( layer != B_Mask && layer != F_Mask )
|
||||
thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
|
||||
|
||||
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer );
|
||||
|
||||
if( layer == Edge_Cuts )
|
||||
|
|
|
@ -129,10 +129,10 @@ void SetGLColor( EDA_COLOR_T color, double alpha )
|
|||
{
|
||||
const StructColors &colordata = g_ColorRefs[ColorGetBase( color )];
|
||||
|
||||
double red = colordata.m_Red / 255.0;
|
||||
double blue = colordata.m_Blue / 255.0;
|
||||
double green = colordata.m_Green / 255.0;
|
||||
glColor4f( red, green, blue, alpha );
|
||||
float red = colordata.m_Red / 255.0;
|
||||
float blue = colordata.m_Blue / 255.0;
|
||||
float green = colordata.m_Green / 255.0;
|
||||
glColor4f( red, green, blue, (float)alpha );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ void EDA_3D_CANVAS::setGLCopperColor()
|
|||
|
||||
// Helper function: initialize the color to draw the epoxy
|
||||
// body board in realistic mode.
|
||||
void EDA_3D_CANVAS::setGLEpoxyColor( double aTransparency )
|
||||
void EDA_3D_CANVAS::setGLEpoxyColor( float aTransparency )
|
||||
{
|
||||
// Generates an epoxy color, near board color
|
||||
SetGLColor( GetPrm3DVisu().m_BoardBodyColor, aTransparency );
|
||||
|
@ -126,7 +126,7 @@ void EDA_3D_CANVAS::setGLEpoxyColor( double aTransparency )
|
|||
|
||||
// Helper function: initialize the color to draw the
|
||||
// solder mask layers in realistic mode.
|
||||
void EDA_3D_CANVAS::setGLSolderMaskColor( double aTransparency )
|
||||
void EDA_3D_CANVAS::setGLSolderMaskColor( float aTransparency )
|
||||
{
|
||||
// Generates a solder mask color
|
||||
SetGLColor( GetPrm3DVisu().m_SolderMaskColor, aTransparency );
|
||||
|
|
|
@ -73,8 +73,6 @@ void SetOpenGlDefaultMaterial()
|
|||
|
||||
bool S3D_MATERIAL::SetOpenGLMaterial( unsigned int aMaterialIndex, bool aUseMaterial )
|
||||
{
|
||||
S3D_MASTER * s3dParent = (S3D_MASTER *) GetParent();
|
||||
|
||||
if( aUseMaterial )
|
||||
{
|
||||
float transparency_value = 0.0f;
|
||||
|
|
|
@ -113,6 +113,11 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
|
|||
|
||||
if( !isTransparent && aIsRenderingJustTransparentObjects )
|
||||
return;
|
||||
|
||||
if( useMaterial )
|
||||
if( m_Materials->m_Transparency.size() > 0 )
|
||||
if( m_Materials->m_Transparency[0] >= 1.0f )
|
||||
return;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
|
@ -146,6 +151,11 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
|
|||
|
||||
if( !isTransparent && aIsRenderingJustTransparentObjects )
|
||||
continue;
|
||||
|
||||
if( useMaterial )
|
||||
if( m_Materials->m_Transparency.size() > idx )
|
||||
if( m_Materials->m_Transparency[idx] >= 1.0f )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Mario Luzeiro <mrluzeiro@gmail.com>
|
||||
* Copyright (C) 1992-2015 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "CImage.h"
|
||||
|
||||
#define CLAMP(n, min, max) {if (n < min) n=min; else if (n > max) n = max;}
|
||||
|
||||
|
||||
CIMAGE::CIMAGE( unsigned int xsize, unsigned int ysize )
|
||||
{
|
||||
m_pixels = (unsigned char*)malloc( xsize * ysize );
|
||||
m_width = xsize;
|
||||
m_height = ysize;
|
||||
m_wxh = xsize * ysize;
|
||||
m_wraping = (E_WRAP)WRAP_CLAMP;
|
||||
}
|
||||
|
||||
|
||||
CIMAGE::~CIMAGE()
|
||||
{
|
||||
free( m_pixels );
|
||||
}
|
||||
|
||||
|
||||
bool CIMAGE::wrapCoords( int *xo, int *yo )
|
||||
{
|
||||
int x = *xo;
|
||||
int y = *yo;
|
||||
|
||||
switch(m_wraping)
|
||||
{
|
||||
case WRAP_CLAMP:
|
||||
x = (x < 0 )?0:x;
|
||||
x = (x >= (int)(m_width - 1))?(m_width - 1):x;
|
||||
y = (y < 0)?0:y;
|
||||
y = (y >= (int)(m_height - 1))?(m_height - 1):y;
|
||||
break;
|
||||
case WRAP_WRAP:
|
||||
x = (x < 0)?((m_width - 1)+x):x;
|
||||
x = (x >= (int)(m_width - 1))?(x - m_width):x;
|
||||
y = (y < 0)?((m_height - 1)+y):y;
|
||||
y = (y >= (int)(m_height - 1))?(y - m_height):y;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( (x < 0) || (x >= (int)m_width) || (y < 0) || (y >= (int)m_height))
|
||||
return false;
|
||||
|
||||
*xo = x;
|
||||
*yo = y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CIMAGE::setpixel( int x, int y, unsigned char value )
|
||||
{
|
||||
if( wrapCoords( &x, &y ) )
|
||||
m_pixels[x + y * m_width] = value;
|
||||
}
|
||||
|
||||
|
||||
unsigned char CIMAGE::getpixel(int x, int y)
|
||||
{
|
||||
if( wrapCoords( &x, &y ) )
|
||||
return m_pixels[x + y * m_width];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CIMAGE::invert()
|
||||
{
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
m_pixels[it] = 255 - m_pixels[it];
|
||||
}
|
||||
|
||||
|
||||
void CIMAGE::copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOperation )
|
||||
{
|
||||
int aV, bV;
|
||||
|
||||
if( aOperation == COPY_RAW )
|
||||
{
|
||||
if ( aImgA == NULL )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (aImgA == NULL) || (aImgB == NULL) )
|
||||
return;
|
||||
}
|
||||
|
||||
switch(aOperation)
|
||||
{
|
||||
case COPY_RAW:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
m_pixels[it] = aImgA->m_pixels[it];
|
||||
break;
|
||||
|
||||
case COPY_ADD:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
aV = aImgA->m_pixels[it];
|
||||
bV = aImgB->m_pixels[it];
|
||||
|
||||
aV = (aV + bV);
|
||||
aV = (aV > 255)?255:aV;
|
||||
|
||||
m_pixels[it] = aV;
|
||||
}
|
||||
break;
|
||||
|
||||
case COPY_SUB:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
aV = aImgA->m_pixels[it];
|
||||
bV = aImgB->m_pixels[it];
|
||||
|
||||
aV = (aV - bV);
|
||||
aV = (aV < 0)?0:aV;
|
||||
|
||||
m_pixels[it] = aV;
|
||||
}
|
||||
break;
|
||||
|
||||
case COPY_DIF:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
aV = aImgA->m_pixels[it];
|
||||
bV = aImgB->m_pixels[it];
|
||||
|
||||
m_pixels[it] = abs(aV - bV);
|
||||
}
|
||||
break;
|
||||
|
||||
case COPY_MUL:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
aV = aImgA->m_pixels[it];
|
||||
bV = aImgB->m_pixels[it];
|
||||
|
||||
m_pixels[it] = (unsigned char)((((float)aV / 255.0f) * ((float)bV / 255.0f)) * 255);
|
||||
}
|
||||
break;
|
||||
|
||||
case COPY_AND:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
m_pixels[it] = aImgA->m_pixels[it] & aImgB->m_pixels[it];
|
||||
}
|
||||
break;
|
||||
|
||||
case COPY_OR:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
m_pixels[it] = aImgA->m_pixels[it] | aImgB->m_pixels[it];
|
||||
}
|
||||
break;
|
||||
|
||||
case COPY_XOR:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
m_pixels[it] = aImgA->m_pixels[it] ^ aImgB->m_pixels[it];
|
||||
}
|
||||
break;
|
||||
|
||||
case COPY_BLEND50:
|
||||
break;
|
||||
|
||||
case COPY_MIN:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
aV = aImgA->m_pixels[it];
|
||||
bV = aImgB->m_pixels[it];
|
||||
|
||||
m_pixels[it] = (aV < bV)?aV:bV;
|
||||
}
|
||||
break;
|
||||
|
||||
case COPY_MAX:
|
||||
for( unsigned int it = 0;it < m_wxh; it++ )
|
||||
{
|
||||
aV = aImgA->m_pixels[it];
|
||||
bV = aImgB->m_pixels[it];
|
||||
|
||||
m_pixels[it] = (aV > bV)?aV:bV;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
S_FILTER FILTERS[9] = {
|
||||
// Hi Pass
|
||||
{
|
||||
{ { 0, -1, -1, -1, 0},
|
||||
{-1, 2, -4, 2, -1},
|
||||
{-1, -4, 13, -4, -1},
|
||||
{-1, 2, -4, 2, -1},
|
||||
{ 0, -1, -1, -1, 0}
|
||||
},
|
||||
7,
|
||||
255
|
||||
},
|
||||
|
||||
// Blur
|
||||
{
|
||||
{ { 3, 5, 7, 5, 3},
|
||||
{ 4, 9, 12, 9, 5},
|
||||
{ 7, 12, 20, 12, 7},
|
||||
{ 4, 9, 12, 9, 5},
|
||||
{ 3, 5, 7, 5, 3}
|
||||
},
|
||||
180,
|
||||
0
|
||||
},
|
||||
|
||||
|
||||
// KS 01
|
||||
{
|
||||
{ { 0, 2, 4, 2, 0},
|
||||
{ 2, -2, 1, -2, 2},
|
||||
{ 4, 1, -8, 1, 4},
|
||||
{ 2, -2, 1, -2, 2},
|
||||
{ 0, 2, 4, 2, 0}
|
||||
},
|
||||
20,
|
||||
0
|
||||
},
|
||||
|
||||
// Cartoon
|
||||
{
|
||||
{ {-1, -1, -1, -1, 0},
|
||||
{-1, 0, 0, 0, 0},
|
||||
{-1, 0, 4, 0, 0},
|
||||
{ 0, 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 0, 4}
|
||||
},
|
||||
3,
|
||||
0
|
||||
},
|
||||
|
||||
// Emboss
|
||||
{
|
||||
{ {-1, -1, -1, -1, 0},
|
||||
{-1, -1, -1, 0, 1},
|
||||
{-1, -1, 0, 1, 1},
|
||||
{-1, 0, 1, 1, 1},
|
||||
{ 0, 1, 1, 1, 1}
|
||||
},
|
||||
1,
|
||||
128
|
||||
},
|
||||
|
||||
// Sharpen
|
||||
{
|
||||
{ {-1, -1, -1, -1, -1},
|
||||
{-1, 2, 2, 2, -1},
|
||||
{-1, 2, 8, 2, -1},
|
||||
{-1, 2, 2, 2, -1},
|
||||
{-1, -1, -1, -1, -1}
|
||||
},
|
||||
8,
|
||||
0
|
||||
},
|
||||
|
||||
// Melt
|
||||
{
|
||||
{ { 4, 2, 6, 8, 1},
|
||||
{ 1, 2, 5, 4, 2},
|
||||
{ 0, -1, 1, -1, 0},
|
||||
{ 0, 0, -2, 0, 0},
|
||||
{ 0, 0, 0, 0, 0}
|
||||
},
|
||||
32,
|
||||
0
|
||||
},
|
||||
|
||||
// Sobel Gx
|
||||
{
|
||||
{ { 0, 0, 0, 0, 0},
|
||||
{ 0, -1, 0, 1, 0},
|
||||
{ 0, -2, 0, 2, 0},
|
||||
{ 0, -1, 0, 1, 0},
|
||||
{ 0, 0, 0, 0, 0}
|
||||
},
|
||||
1,
|
||||
0
|
||||
},
|
||||
|
||||
// Sobel Gy
|
||||
{
|
||||
{ { 1, 2, 4, 2, 1},
|
||||
{-1, -1, 0, 1, 1},
|
||||
{-2, -2, 0, 2, 2},
|
||||
{-1, -1, 0, 1, 1},
|
||||
{-1, -2, -4, -2, -1},
|
||||
},
|
||||
1,
|
||||
0
|
||||
}
|
||||
};// Filters
|
||||
|
||||
|
||||
void CIMAGE::efxFilter( CIMAGE *aInImg, float aGain, E_FILTER aFilterType )
|
||||
{
|
||||
S_FILTER filter = FILTERS[aFilterType];
|
||||
|
||||
aInImg->m_wraping = WRAP_CLAMP;
|
||||
m_wraping = WRAP_CLAMP;
|
||||
|
||||
for( int iy = 0; iy < (int)m_height; iy++)
|
||||
{
|
||||
for( int ix = 0; ix < (int)m_width; ix++ )
|
||||
{
|
||||
int v = filter.offset;
|
||||
|
||||
for( int sy = 0; sy < 5; sy++ )
|
||||
{
|
||||
for( int sx = 0; sx < 5; sx++ )
|
||||
{
|
||||
int factor = filter.kernel[sx][sy];
|
||||
unsigned char pixelv = aInImg->getpixel( ix + sx - 2, iy + sy - 2 );
|
||||
v += pixelv * factor;
|
||||
}
|
||||
}
|
||||
|
||||
v /= filter.div;
|
||||
|
||||
CLAMP(v, 0, 255);
|
||||
|
||||
m_pixels[ix + iy * m_width] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CIMAGE::setPixelsFromNormalizedFloat( const float * aNormalizedFloatArray )
|
||||
{
|
||||
for( unsigned int i = 0; i < m_wxh; i++ )
|
||||
{
|
||||
int v = aNormalizedFloatArray[i] * 255;
|
||||
CLAMP(v, 0, 255);
|
||||
m_pixels[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CIMAGE::saveAsPNG( wxString aFileName )
|
||||
{
|
||||
unsigned char* pixelbuffer = (unsigned char*) malloc( m_wxh * 3 );
|
||||
//unsigned char* alphabuffer = (unsigned char*) malloc( m_width * aHeight );
|
||||
|
||||
wxImage image( m_width, m_height );
|
||||
|
||||
for( unsigned int i = 0; i < m_wxh; i++)
|
||||
{
|
||||
unsigned char v = m_pixels[i];
|
||||
pixelbuffer[i * 3 + 0] = v;
|
||||
pixelbuffer[i * 3 + 1] = v;
|
||||
pixelbuffer[i * 3 + 2] = v;
|
||||
//alphabuffer[i * 1 + 0] = aRGBABufferImage[i * 4 + 3];
|
||||
}
|
||||
|
||||
image.SetData( pixelbuffer );
|
||||
//image.SetAlpha( alphabuffer );
|
||||
image = image.Mirror( false );
|
||||
image.SaveFile( aFileName + ".png", wxBITMAP_TYPE_PNG );
|
||||
image.Destroy();
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015 Mario Luzeiro <mrluzeiro@gmail.com>
|
||||
* Copyright (C) 1992-2015 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef CImage_h
|
||||
#define CImage_h
|
||||
|
||||
#include <wx/image.h>
|
||||
|
||||
enum E_IMAGE_OP {
|
||||
COPY_RAW,
|
||||
COPY_ADD,
|
||||
COPY_SUB,
|
||||
COPY_DIF,
|
||||
COPY_MUL,
|
||||
COPY_AND,
|
||||
COPY_OR,
|
||||
COPY_XOR,
|
||||
COPY_BLEND50,
|
||||
COPY_MIN,
|
||||
COPY_MAX
|
||||
};
|
||||
|
||||
enum E_WRAP {
|
||||
WRAP_ZERO, ///< Coords that wraps are not evaluated
|
||||
WRAP_CLAMP,
|
||||
WRAP_WRAP ///< Coords are wrapped arround
|
||||
};
|
||||
|
||||
enum E_FILTER {
|
||||
FILTER_HIPASS,
|
||||
FILTER_BLUR
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
signed char kernel[5][5];
|
||||
unsigned char div;
|
||||
unsigned char offset;
|
||||
}S_FILTER;
|
||||
|
||||
|
||||
class CIMAGE
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
CIMAGE( unsigned int xsize, unsigned int ysize );
|
||||
|
||||
~CIMAGE();
|
||||
|
||||
void setpixel( int x, int y, unsigned char value );
|
||||
unsigned char getpixel( int x, int y );
|
||||
|
||||
void copyFull( const CIMAGE *aImgA, const CIMAGE *aImgB, E_IMAGE_OP aOperation );
|
||||
|
||||
void invert();
|
||||
|
||||
void efxFilter( CIMAGE *aInImg, float aGain, E_FILTER aFilterType );
|
||||
|
||||
void saveAsPNG( wxString aFileName );
|
||||
|
||||
void setPixelsFromNormalizedFloat( const float * aNormalizedFloatArray );
|
||||
private:
|
||||
bool wrapCoords( int *xo, int *yo );
|
||||
|
||||
public:
|
||||
unsigned char* m_pixels;
|
||||
unsigned int m_width;
|
||||
unsigned int m_height;
|
||||
unsigned int m_wxh;
|
||||
E_WRAP m_wraping;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -30,6 +30,7 @@ set(3D-VIEWER_SRCS
|
|||
vrml_v1_modelparser.cpp
|
||||
vrml_v2_modelparser.cpp
|
||||
x3dmodelparser.cpp
|
||||
CImage.cpp
|
||||
)
|
||||
|
||||
add_library(3d-viewer STATIC ${3D-VIEWER_SRCS})
|
||||
|
|
|
@ -183,9 +183,7 @@ public: INFO3D_VISU();
|
|||
*/
|
||||
int GetNonCopperLayerThicknessBIU() const
|
||||
{
|
||||
bool use_thickness = GetFlag( FL_USE_COPPER_THICKNESS )
|
||||
// || GetFlag( FL_USE_REALISTIC_MODE )
|
||||
;
|
||||
bool use_thickness = GetFlag( FL_USE_COPPER_THICKNESS );
|
||||
return use_thickness ?
|
||||
KiROUND( m_nonCopperLayerThickness / m_BiuTo3Dunits )
|
||||
: 0;
|
||||
|
@ -202,8 +200,7 @@ public: INFO3D_VISU();
|
|||
{
|
||||
return IsCopperLayer( aLayerId ) ?
|
||||
GetCopperThicknessBIU() :
|
||||
GetNonCopperLayerThicknessBIU()
|
||||
;
|
||||
GetNonCopperLayerThicknessBIU();
|
||||
}
|
||||
|
||||
bool IsRealisticMode() { return GetFlag( FL_USE_REALISTIC_MODE ); }
|
||||
|
|
Loading…
Reference in New Issue