You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
6.3 KiB

18 years ago
  1. /**************************************/
  2. /* Code to handle schematic clean up. */
  3. /**************************************/
  4. #include "fctsys.h"
  5. #include "appl_wxstruct.h"
  6. #include "common.h"
  7. #include "trigo.h"
  8. #include "confirm.h"
  9. #include "macros.h"
  10. #include "program.h"
  11. #include "general.h"
  12. #include "protos.h"
  13. #include "netlist.h"
  14. static int TstAlignSegment( SCH_LINE* RefSegm, SCH_LINE* TstSegm );
  15. /* Routine cleaning:
  16. * - Includes segments or buses aligned in only 1 segment
  17. * - Detects identical objects superimposed
  18. */
  19. bool SCH_SCREEN::SchematicCleanUp( wxDC* DC )
  20. {
  21. SCH_ITEM* DrawList, * TstDrawList;
  22. int flag;
  23. bool Modify = FALSE;
  24. DrawList = EEDrawList;
  25. for( ; DrawList != NULL; DrawList = DrawList->Next() )
  26. {
  27. if( DrawList->Type() == DRAW_SEGMENT_STRUCT_TYPE )
  28. {
  29. TstDrawList = DrawList->Next();
  30. while( TstDrawList )
  31. {
  32. if( TstDrawList->Type() == DRAW_SEGMENT_STRUCT_TYPE )
  33. {
  34. flag = TstAlignSegment( (SCH_LINE*) DrawList,
  35. (SCH_LINE*) TstDrawList );
  36. if( flag )
  37. {
  38. /* keep the bits set in .m_Flags, because the deleted
  39. * segment can be flagged */
  40. DrawList->m_Flags |= TstDrawList->m_Flags;
  41. EraseStruct( TstDrawList, this );
  42. SetRefreshReq();
  43. TstDrawList = EEDrawList;
  44. Modify = TRUE;
  45. }
  46. else
  47. TstDrawList = TstDrawList->Next();
  48. }
  49. else
  50. TstDrawList = TstDrawList->Next();
  51. }
  52. }
  53. }
  54. WinEDA_SchematicFrame* frame;
  55. frame = (WinEDA_SchematicFrame*) wxGetApp().GetTopWindow();
  56. frame->TestDanglingEnds( EEDrawList, DC );
  57. return Modify;
  58. }
  59. /* Routine to start/end segment (BUS or wires) on junctions.
  60. */
  61. void BreakSegmentOnJunction( SCH_SCREEN* Screen )
  62. {
  63. SCH_ITEM* DrawList;
  64. if( Screen == NULL )
  65. {
  66. DisplayError( NULL,
  67. wxT( "BreakSegmentOnJunction() error: NULL screen" ) );
  68. return;
  69. }
  70. DrawList = Screen->EEDrawList;
  71. while( DrawList )
  72. {
  73. switch( DrawList->Type() )
  74. {
  75. case DRAW_JUNCTION_STRUCT_TYPE:
  76. #undef STRUCT
  77. #define STRUCT ( (SCH_JUNCTION*) DrawList )
  78. BreakSegment( Screen, STRUCT->m_Pos );
  79. break;
  80. case DRAW_BUSENTRY_STRUCT_TYPE:
  81. #undef STRUCT
  82. #define STRUCT ( (SCH_BUS_ENTRY*) DrawList )
  83. BreakSegment( Screen, STRUCT->m_Pos );
  84. BreakSegment( Screen, STRUCT->m_End() );
  85. break;
  86. case DRAW_SEGMENT_STRUCT_TYPE:
  87. case DRAW_NOCONNECT_STRUCT_TYPE:
  88. case TYPE_SCH_LABEL:
  89. case TYPE_SCH_GLOBALLABEL:
  90. case TYPE_SCH_HIERLABEL:
  91. case TYPE_SCH_COMPONENT:
  92. case DRAW_POLYLINE_STRUCT_TYPE:
  93. case TYPE_SCH_MARKER:
  94. case TYPE_SCH_TEXT:
  95. case DRAW_SHEET_STRUCT_TYPE:
  96. case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE:
  97. break;
  98. default:
  99. break;
  100. }
  101. DrawList = DrawList->Next();
  102. }
  103. }
  104. /* Break a segment ( BUS, WIRE ) int 2 segments at location aBreakpoint,
  105. * if aBreakpoint in on segment segment
  106. * ( excluding ends)
  107. * fill aPicklist with modified items if non null
  108. */
  109. void BreakSegment( SCH_SCREEN* aScreen, wxPoint aBreakpoint )
  110. {
  111. SCH_LINE* segment, * NewSegment;
  112. for( SCH_ITEM* DrawList = aScreen->EEDrawList; DrawList;
  113. DrawList = DrawList->Next() )
  114. {
  115. if( DrawList->Type() != DRAW_SEGMENT_STRUCT_TYPE )
  116. continue;
  117. segment = (SCH_LINE*) DrawList;
  118. if( !TestSegmentHit( aBreakpoint, segment->m_Start, segment->m_End, 0 ) )
  119. continue;
  120. /* ???
  121. * Segment connecte: doit etre coupe en 2 si px,py
  122. * n'est
  123. * pas une extremite */
  124. if( ( segment->m_Start == aBreakpoint )
  125. || ( segment->m_End == aBreakpoint ) )
  126. continue;
  127. /* Here we must cut the segment into 2. */
  128. NewSegment = segment->GenCopy();
  129. NewSegment->m_Start = aBreakpoint;
  130. segment->m_End = NewSegment->m_Start;
  131. NewSegment->SetNext( segment->Next() );
  132. segment->SetNext( NewSegment );
  133. DrawList = NewSegment;
  134. }
  135. }
  136. /* Search if the 2 segments RefSegm and TstSegm are on a line.
  137. * Return 0 if no
  138. * 1 if yes, and RefSegm is modified to be the equivalent segment
  139. */
  140. static int TstAlignSegment( SCH_LINE* RefSegm, SCH_LINE* TstSegm )
  141. {
  142. if( RefSegm == TstSegm )
  143. return 0;
  144. if( RefSegm->GetLayer() != TstSegm->GetLayer() )
  145. return 0;
  146. // search for a common end, and modify coordinates to ensure RefSegm->m_End
  147. // == TstSegm->m_Start
  148. if( RefSegm->m_Start == TstSegm->m_Start )
  149. {
  150. if( RefSegm->m_End == TstSegm->m_End )
  151. return 1;
  152. EXCHG( RefSegm->m_Start, RefSegm->m_End );
  153. }
  154. else if( RefSegm->m_Start == TstSegm->m_End )
  155. {
  156. EXCHG( RefSegm->m_Start, RefSegm->m_End );
  157. EXCHG( TstSegm->m_Start, TstSegm->m_End );
  158. }
  159. else if( RefSegm->m_End == TstSegm->m_End )
  160. {
  161. EXCHG( TstSegm->m_Start, TstSegm->m_End );
  162. }
  163. else if( RefSegm->m_End != TstSegm->m_Start )
  164. // No common end point, segments cannot be merged.
  165. return 0;
  166. /* Test alignment: */
  167. if( RefSegm->m_Start.y == RefSegm->m_End.y ) // Horizontal segment
  168. {
  169. if( TstSegm->m_Start.y == TstSegm->m_End.y )
  170. {
  171. RefSegm->m_End = TstSegm->m_End;
  172. return 1;
  173. }
  174. }
  175. else if( RefSegm->m_Start.x == RefSegm->m_End.x ) // Vertical segment
  176. {
  177. if( TstSegm->m_Start.x == TstSegm->m_End.x )
  178. {
  179. RefSegm->m_End = TstSegm->m_End;
  180. return 1;
  181. }
  182. }
  183. else
  184. {
  185. if( atan2( (double) ( RefSegm->m_Start.x - RefSegm->m_End.x ),
  186. (double) ( RefSegm->m_Start.y - RefSegm->m_End.y ) ) ==
  187. atan2( (double) ( TstSegm->m_Start.x - TstSegm->m_End.x ),
  188. (double) ( TstSegm->m_Start.y - TstSegm->m_End.y ) ) )
  189. {
  190. RefSegm->m_End = TstSegm->m_End;
  191. return 1;
  192. }
  193. }
  194. return 0;
  195. }