| 1043 | //------------------------------------------------------------------------------ |
| 1044 | |
| 1045 | bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) |
| 1046 | { |
| 1047 | #ifdef use_lines |
| 1048 | if (!Closed && PolyTyp == ptClip) |
| 1049 | throw clipperException("AddPath: Open paths must be subject."); |
| 1050 | #else |
| 1051 | if (!Closed) |
| 1052 | throw clipperException("AddPath: Open paths have been disabled."); |
| 1053 | #endif |
| 1054 | |
| 1055 | int highI = (int)pg.size() -1; |
| 1056 | if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI; |
| 1057 | while (highI > 0 && (pg[highI] == pg[highI -1])) --highI; |
| 1058 | if ((Closed && highI < 2) || (!Closed && highI < 1)) return false; |
| 1059 | |
| 1060 | //create a new edge array ... |
| 1061 | TEdge *edges = new TEdge [highI +1]; |
| 1062 | |
| 1063 | bool IsFlat = true; |
| 1064 | //1. Basic (first) edge initialization ... |
| 1065 | try |
| 1066 | { |
| 1067 | edges[1].Curr = pg[1]; |
| 1068 | RangeTest(pg[0], m_UseFullRange); |
| 1069 | RangeTest(pg[highI], m_UseFullRange); |
| 1070 | InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]); |
| 1071 | InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]); |
| 1072 | for (int i = highI - 1; i >= 1; --i) |
| 1073 | { |
| 1074 | RangeTest(pg[i], m_UseFullRange); |
| 1075 | InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]); |
| 1076 | } |
| 1077 | } |
| 1078 | catch(...) |
| 1079 | { |
| 1080 | delete [] edges; |
| 1081 | throw; //range test fails |
| 1082 | } |
| 1083 | TEdge *eStart = &edges[0]; |
| 1084 | |
| 1085 | //2. Remove duplicate vertices, and (when closed) collinear edges ... |
| 1086 | TEdge *E = eStart, *eLoopStop = eStart; |
| 1087 | for (;;) |
| 1088 | { |
| 1089 | //nb: allows matching start and end points when not Closed ... |
| 1090 | if (E->Curr == E->Next->Curr && (Closed || E->Next != eStart)) |
| 1091 | { |
| 1092 | if (E == E->Next) break; |
| 1093 | if (E == eStart) eStart = E->Next; |
| 1094 | E = RemoveEdge(E); |
| 1095 | eLoopStop = E; |
| 1096 | continue; |
| 1097 | } |
| 1098 | if (E->Prev == E->Next) |
| 1099 | break; //only two vertices |
| 1100 | else if (Closed && |
| 1101 | SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) && |
| 1102 | (!m_PreserveCollinear || |
no test coverage detected