← Back to team overview

kicad-developers team mailing list archive

Re: pcbnew - thermal connections patch proposal

 

Hi

I have coded a new thermal connection algorithm which uses tracks
(SEGZONE) instead of the polygons. I have started doing this because
the results of polygon thermal conection is sometimes ugly (see
atachment so8 footprint).

Now you get more freedom with setting minimal zone thicknes (it doesn't
need to be less than copper track width) and you can choose to have
different thermal patterns (not yet implemented).

I have a problem with generating connection to the zone (ratsnet).
What do I have to do for ratsnet calculation to work correctly.

Mery christmas,
Rok

jean-pierre.charras@... pravi:
> Rok Markovic a écrit :
>> Hi
>>
>> I must say that the new zone system is very good.
>>
>> There is something that bothers me. Thermal pattern for smd
>> pads, usualy for SO packages is a bit ugly. I would like to
>> improve thermal patterns handling and I am going to made a
>> proposition.
>>
>> Drawing zones:
>> - Compute m_FilledPolygon with all Pads excluded except for
>> PAD_IN_ZONE, which is of course included.
>> - Compute and remove Isolated and unconected islands which are smaller
>> than area specified in the dialog_zone_settings via new variable.
>> 
> This is already done.
>> - Do something similiar as in GenrePadConection()
>> - Final RemoveIsolatedAndUnconnected islands.
>>
>> I would like to know two things:
>> 1. How to compute area in kbool polygons
>> 
> kbool is a *very* powerfull library
> 
> polygon/kbool/samples/boolonly has a useful example. (see also 
> kbool/include/kbool/booleng.h and its comments)
> 
> 1 - create a bool engine instance
> see void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) in 
> polygon/PolyLine.cpp
> 
> a " Bool_Engine" has 2 polygons buffers: GROUP_A and GROUP_B
> for operation involving only one polygon GROUP_A is used (shrink 
> smooth ..)
> for operation involving two polygon GROUP_A and GROUP_B are used ( 
> AND OR (ADD) XOR SUBSTRACT... operations)
> 
> 2 - enter main polygon(s) (like area outline) in GROUP_A
> 3 - enter polygons to ADD , SUBSTRACT ... in GROUP_B, polugon by polygon
> 4 - Call Do_Operation()
> 5 - read the resulting polygon(s)
> 
> see zones_convert_brd_items_to_polygons.cpp as an example.
> 
>> 2. How to determin if the point is inside or outside of the polygon
>> 
> See my last update:
> polygon/polygon_test_point_inside.cpp (updated comments inside) and 
> polygon/determine_if_point_inside_polygon.odt
>> First one is not mandatory but will improve zone look.
>>
>> Second information I need for computing which thermal connection is
>> actually connected to the zone.
>>
>> I hope I will improve zone drawing (from good to a bit better).
>>
>> Rok
>>
>> 
> 
> 

-- 
Kanardia d.o.o.
ul. heroja Roj¹ka 70
3000 Celje
Tel: +386 3 424 42 42
Fax: +386 3 424 41 95
 --------------020808040704020506050502 Content-Type: text/x-diff;
name="thermal.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="thermal.patch"

--- pcbnew/zones_convert_brd_items_to_polygons.cpp	(revision 1488)
+++ pcbnew/zones_convert_brd_items_to_polygons.cpp	(working copy)
@@ -175,21 +175,12 @@
switch( m_PadOption )
{
case PAD_NOT_IN_ZONE:
+ case THERMAL_PAD:
item_boundingbox = pad->GetBoundingBox();
if( item_boundingbox.Intersects( zone_boundingbox ) )
AddPadWithClearancePolygon( booleng, *pad, clearance );
break;

- case THERMAL_PAD:
- item_boundingbox = pad->GetBoundingBox();
- item_boundingbox.Inflate( m_ThermalReliefGapValue, m_ThermalReliefGapValue );
- if( item_boundingbox.Intersects( zone_boundingbox ) )
- AddThermalReliefPadPolygon( booleng, *pad,
- m_ThermalReliefGapValue,
- m_ThermalReliefCopperBridgeValue,
- m_ZoneMinThickness );
- break;
-
case PAD_IN_ZONE:
break;
}
@@ -246,6 +237,54 @@
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
delete booleng;

+ // first compute endindex for TestPointInsidePolygon
+ unsigned int indexstart = 0, indexend;
+ for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ )
+ {
+ if( m_FilledPolysList[indexend].end_contour ) // end of a filled sub-area found
+ {
+ break;
+ }
+ }
+
+ // find all thermal connected pads
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
+ {
+ if( pad->IsOnLayer( GetLayer() )
+ && pad->GetNet() == GetNet()
+ && m_PadOption == THERMAL_PAD )
+ {
+ // test point
+ int dx = (pad->m_Size.x / 2) + m_ThermalReliefGapValue+m_ZoneMinThickness;
+ int dy = (pad->m_Size.y / 2) + m_ThermalReliefGapValue+m_ZoneMinThickness;
+
+ // compute north, south, west and east points for zone connection.
+ wxPoint ptTest[4];
+ ptTest[0] = pad->GetPosition() + wxPoint(0, dy);
+ ptTest[1] = pad->GetPosition() + wxPoint(0, -dy);
+ ptTest[2] = pad->GetPosition() + wxPoint( dx, 0);
+ ptTest[3] = pad->GetPosition() + wxPoint(-dx, 0);
+
+ for (int i=0; i<4; i++) {
+ if ( TestPointInsidePolygon( m_FilledPolysList, indexstart,
+ indexend, ptTest[i].x, ptTest[i].y ) )
+ {
+ SEGZONE* segment = new SEGZONE( aPcb );
+ segment->m_Start = pad->GetPosition();
+ segment->m_End = ptTest[i];
+ segment->SetNet( GetNet() );
+ segment->m_TimeStamp = m_TimeStamp;
+ segment->m_Width = m_ThermalReliefCopperBridgeValue;
+ segment->SetLayer( GetLayer() );
+ aPcb->Add( segment );
+ }
+ }
+ }
+ }
+ }
+
// Remove insulated islands:
if( GetNet() > 0 )
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
 --------------020808040704020506050502 Content-Type: image/png;
name="thermal.png"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="thermal.png"

[Attachment content not displayed.] --------------020808040704020506050502-- 




Follow ups

References