void DList_Erase( DList *self, daoint start, daoint n ) { void **buf = self->items.pVoid - self->offset; daoint rest; if( start >= self->size ) return; if( n < 0 ) n = self->size; if( n > self->size - start ) n = self->size - start; if( n == 1 ){ if( start == 0 ){ DList_PopFront( self ); return; }else if( start == self->size -1 ){ DList_PopBack( self ); return; } } DList_DeleteItems( self, start, start+n ); if( self->type == DAO_DATA_VALUE ) DaoGC_LockData(); rest = self->size - start - n; memmove( self->items.pVoid + start, self->items.pVoid + start + n, rest * sizeof(void*) ); self->size -= n; if( self->size < 0.5*self->bufsize && self->size + 10 < self->bufsize ){ if( self->offset ) memmove( buf, self->items.pVoid, self->size * sizeof(void*)); self->bufsize = 0.6 * self->bufsize + 1; self->items.pVoid = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->offset = 0; } if( self->type == DAO_DATA_VALUE ) DaoGC_UnlockData(); }
static DaoTaskletEvent* DaoTaskletServer_MakeEvent( DaoTaskletServer *self ) { DaoTaskletEvent *event; DMutex_Lock( & self->mutex ); event = (DaoTaskletEvent*) DList_PopBack( self->caches ); if( event == NULL ) event = DaoTaskletEvent_New(); DMutex_Unlock( & self->mutex ); return event; }
DaoXmlNode* DaoXmlDOM_NewNode( DaoXmlDOM *self ) { if( self->caches->size ){ DaoXmlNode *node = DList_Back( self->caches ); DList_PopBack( self->caches ); return node; } return DaoXmlNode_New(); }
static DaoTaskEvent* DaoCallServer_MakeEvent() { DaoTaskEvent *event; DaoCallServer *server = daoCallServer; DMutex_Lock( & server->mutex ); event = (DaoTaskEvent*) DList_PopBack( server->caches ); if( event == NULL ) event = DaoTaskEvent_New(); DMutex_Unlock( & server->mutex ); return event; }
static void NODE_Search( DaoProcess *proc, DaoValue *p[], int N ) { DList *nodes; DaoList *list = DaoProcess_PutList( proc ); DaoxNode *self = (DaoxNode*) p[0]; DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 1 ); daoint method = p[1]->xEnum.value; daoint which = p[2]->xEnum.value; daoint i, j, entry; if( sect == NULL ) return; for(i=0; i<self->graph->nodes->size; i++){ DaoxNode *node = (DaoxNode*) self->graph->nodes->items.pVoid[i]; node->state = 0; } nodes = DList_New(0); DList_PushBack( nodes, self ); entry = proc->topFrame->entry; while( nodes->size ){ DaoxNode *node = NULL; if( method ){ node = (DaoxNode*) DList_Front( nodes ); DList_PopFront( nodes ); }else{ node = (DaoxNode*) DList_Back( nodes ); DList_PopBack( nodes ); } if( node->state ) continue; node->state = 1; if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, (DaoValue*) node ); proc->topFrame->entry = entry; DaoProcess_Execute( proc ); if( proc->status == DAO_PROCESS_ABORTED ) break; if( proc->stackValues[0]->xInteger.value ){ DaoList_PushBack( list, (DaoValue*) node ); if( which == 0 ) break; } for(j=0; j<node->outs->size; j++){ DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j]; DaoxNode *node2 = node == edge->first ? edge->second : edge->first; DList_PushBack( nodes, node2 ); } } DaoProcess_PopFrame( proc ); DList_Delete( nodes ); }
void DaoxNode_DepthFirstSearch( DaoxNode *self, DList *nodes ) { DList *stack = DList_New(0); daoint j; DList_Clear( nodes ); DList_PushBack( stack, self ); while( stack->size ){ DaoxNode *node = (DaoxNode*) DList_Back( stack ); DList_PopBack( stack ); if( node->state ) continue; node->state = 1; DList_PushBack( nodes, node ); for(j=0; j<node->outs->size; j++){ DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j]; DaoxNode *node2 = node == edge->first ? edge->second : edge->first; DList_PushBack( stack, node2 ); } } DList_Delete( stack ); }
static void DaoSTD_Try( DaoProcess *proc, DaoValue *p[], int n ) { DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 0 ); int i, ecount = proc->exceptions->size; if( sect == NULL ) return; DaoProcess_Execute( proc ); DaoProcess_PopFrame( proc ); if( proc->exceptions->size > (ecount+1) ){ DaoList *list = DaoProcess_PutList( proc ); for(i=ecount; i<proc->exceptions->size; ++i){ DaoList_Append( list, proc->exceptions->items.pValue[i] ); } DList_Erase( proc->exceptions, ecount, -1 ); }else if( proc->exceptions->size > ecount ){ DaoProcess_PutValue( proc, proc->exceptions->items.pValue[proc->exceptions->size-1] ); DList_PopBack( proc->exceptions ); }else{ DaoProcess_PutValue( proc, proc->stackValues[0] ); } }
void DaoxTriangulator_Triangulate( DaoxTriangulator *self ) { DaoxVertexData *V, *A, *B, *C, *inside; DaoxVector2D PA, PB, PC, P, *points = self->points->data.vectors2d; int i, imin, imax, contours, K = 0, N = self->vertices->size; double dist, area, ymin, ymax, dmax, dmin; double AB, BC, CA, min_area = 1E-16; if( self->vertices->size == 0 ) return; DaoxTriangulator_InitContourOrientation( self ); V = (DaoxVertexData*) self->vertices->items.pVoid[N-1]; contours = V->contour; DList_Assign( self->worklist, self->vertices ); while( self->worklist->size && (++K) < 10*N ){ A = (DaoxVertexData*) self->worklist->items.pVoid[self->worklist->size-1]; if( A->done ){ DList_PopBack( self->worklist ); continue; } B = A->next; C = A->prev; PA = points[A->index]; PB = points[B->index]; PC = points[C->index]; area = DaoxTriangle_Area( PA, PB, PC ); if( B->next == C ){ /* already a triangle: */ if( fabs( area ) > min_area ) DaoxTriangulator_MakeTriangle( self, A ); A->next->prev = A->prev; A->prev->next = A->next; A->done = B->done = C->done = 1; DList_PopBack( self->worklist ); continue; } ymin = ymax = PA.y; if( PB.y < ymin ) ymin = PB.y; else if( PB.y > ymax ) ymax = PB.y; if( PC.y < ymin ) ymin = PC.y; else if( PC.y > ymax ) ymax = PC.y; imin = B->sorting < C->sorting ? B->sorting : C->sorting; imax = A->sorting; inside = NULL; dmax = - 1.0; dmin = 1E9; /* // find the closest point to the triangle: // // Note: no need to distinguish duplicated vertices, because: // 1. if they are outside of the trianlge, they cause no problem; // 2. they cannot be the "closest" vertex to "A" or another vertex again, // so no problem for joining inner contour or splitting outer contour. // // The reason that they cannot be the "closest" vertex is that, // only a concave vertex from the outer contour or a convex // vertex from an inner contour for a hole can be chosen as the // the "closest" vertex. // // And when its original vertex was choose as the "closest" vertex, // the associated "A" will always be processed until it is removed // from the polygon(s), which will leave the duplicated vertices // as convex vertices on the outer contour! */ for(i=imin+1; i<imax; ++i){ V = (DaoxVertexData*) self->vertices->items.pVoid[i]; P = points[V->index]; if( V->done ) continue; //printf( "%3i: %12f %12f %9p, %3i %3i %3i %3i\n", i, P.x, P.y, V, V->contour, A->contour, V->direction, A->direction ); /* Ingore vertex from other contour with the same direction: */ if( V->contour != A->contour && V->direction == A->direction ) continue; if( V->sorting == A->sorting || V->sorting == B->sorting || V->sorting == C->sorting ) continue; if( P.y > ymax ) continue; if( P.y < ymin ) continue; //printf( "%3i: %12f %12f %9p, %3i %3i %3i %3i\n", i, P.x, P.y, V, V->contour, A->contour, V->direction, A->direction ); BC = DaoxTriangle_Area( P, PB, PC ); AB = DaoxTriangle_Area( P, PA, PB ); CA = DaoxTriangle_Area( P, PC, PA ); if( area < 0.0 ){ AB = -AB; BC = -BC; CA = -CA; } //printf( "%3i: %12f %12f %12f\n", i, AB, BC, CA ); if( BC >= 0.0 && AB >= 0.0 && CA >= 0.0 ){ float d = DaoxVector2D_Dist( P, PA ); if( d < dmin ){ dmin = d; inside = V; } } } #if 0 printf( "A: %15f %15f %9p\n", PA.x, PA.y, A ); printf( "B: %15f %15f %9p\n", PB.x, PB.y, B ); printf( "C: %15f %15f %9p\n", PC.x, PC.y, C ); if( inside ) printf( "I: %15f %15f\n", points[inside->index].x, points[inside->index].y ); printf( "%p\n", inside ); printf( "area: %15f\n", area ); #endif if( inside == NULL ){ A->done = 1; //printf( "area: %15f\n", DaoxTriangle_Area( PA, PB, PC ) ); if( fabs( area ) > min_area ) DaoxTriangulator_MakeTriangle( self, A ); A->next->prev = A->prev; A->prev->next = A->next; DList_PopBack( self->worklist ); //if( self->triangles->size >= 3*111 ) break; }else{ /* point inside the triangle: */ DaoxVertexData *A2, *N2; int breaking = inside->contour == A->contour; if( inside->contour != A->contour ){ /* joining contour: */ /* the "inside" vertex is from a hole: */ DaoxVertexData *V2 = inside; //printf( "joining\n" ); /* update contour: */ do { V2->contour = A->contour; V2->direction = A->direction; V2 = V2->next; } while( V2 != inside ); } /* // connect "inside" to "A" with duplicated vertices, this will either: // 1. connect the inner contour with the outer contour; // 2. or break the outer contour. */ N2 = DaoxTriangulator_GetVertex( self, inside->index ); A2 = DaoxTriangulator_GetVertex( self, A->index ); N2->sorting = inside->sorting; A2->sorting = A->sorting; A2->contour = N2->contour = A->contour; A2->direction = N2->direction = A->direction; A2->prev = A->prev; A->prev->next = A2; A2->next = N2; N2->prev = A2; N2->next = inside->next; inside->next->prev = N2; inside->next = A; A->prev = inside; //printf( "dup: %9p %9p\n", A2, N2 ); if( breaking ){ contours += 1; //printf( "contours = %3i\n", contours ); DaoxVertexData *V2 = inside; /* update contour: */ do { V2->contour = contours; V2 = V2->next; } while( V2 != inside ); } DList_PushBack( self->vertices, N2 ); DList_PushBack( self->vertices, A2 ); DList_PopBack( self->worklist ); DList_PushBack( self->worklist, N2 ); DList_PushBack( self->worklist, A2 ); DList_PushBack( self->worklist, A ); } } }