Exemplo n.º 1
0
	static Relation CompressCSGTreeWithOppo(CSGTreeOld* tree, uint32_t Id)
	{
		auto leaf = tree->Leaves[Id];
		CSGTreeNode *curPtr = leaf, *parent = leaf->Parent, *neib;

		while (true)
		{
			if (!parent)
			{
				delete tree->pRoot;
				tree->pRoot = nullptr;
				tree->Leaves.clear();
				return REL_OPPOSITE;
			}
			if (LeftOrRight(curPtr) < 0.0)
				neib = parent->pRight;
			else neib = parent->pLeft;

			if (neib->relation == REL_OPPOSITE)
			{
				curPtr = parent;
				parent = parent->Parent;
			}
			else if (neib->relation == REL_SAME)
			{
				if (parent->Type == TYPE_UNION)
					return CompressCSGTreeWithInside(tree, Id);
				else if (parent->Type == TYPE_INTERSECT)
					return CompressCSGTreeWithOutside(tree, Id);
				else assert(0);
			}
			else break;
		}
		curPtr->relation = REL_OPPOSITE;
        SAFE_DELETE(curPtr->pLeft);
        SAFE_DELETE(curPtr->pRight);
		GetLeafList(tree);
		return REL_NOT_AVAILABLE;
	}
Exemplo n.º 2
0
	static Relation CompressCSGTreeWithOutside(CSGTreeOld* tree, uint32_t Id)
	{
		auto leaf = tree->Leaves[Id];
		CSGTreeNode *curPtr = leaf, *parent = leaf->Parent;
		while (parent && parent->Type == TYPE_INTERSECT)
		{
			curPtr = parent;
			parent = parent->Parent;
		}

		if (!parent) 
		{
			delete tree->pRoot;
			tree->pRoot = nullptr;
			tree->Leaves.clear();
			return REL_OUTSIDE;
		}

		assert(parent->Type == TYPE_UNION);
		int resCur = LeftOrRight(curPtr);
		int resPar = LeftOrRight(parent);

		if (resPar == 0) // root
		{
			if (resCur < 0)
			{
				tree->pRoot = parent->pRight;
				parent->pRight = nullptr;
				delete parent;
			}
			else 
			{
				assert(resCur);
				tree->pRoot = parent->pLeft;
				parent->pLeft = nullptr;
				delete parent;
			}
			tree->pRoot->Parent = nullptr;
		}
		else if (resPar < 0)
		{
			if (resCur < 0)
			{
				parent->pRight->Parent = parent->Parent;
				parent->Parent->pLeft = parent->pRight;
				parent->pRight = nullptr;
				delete parent;
			}
			else 
			{
				assert(resCur);
				parent->pLeft->Parent = parent->Parent;
				parent->Parent->pLeft = parent->pLeft;
				parent->pLeft = nullptr;
				delete parent;
			}
		}
		else
		{
			if (resCur < 0)
			{
				parent->pRight->Parent = parent->Parent;
				parent->Parent->pRight = parent->pRight;
				parent->pRight = nullptr;
				delete parent;
			}
			else 
			{
				assert(resCur);
				parent->pLeft->Parent = parent->Parent;
				parent->Parent->pRight = parent->pLeft;
				parent->pLeft = nullptr;
				delete parent;
			}
		}
		GetLeafList(tree);
		return REL_UNKNOWN;
	}
Exemplo n.º 3
0
// result is the last node (if any... which is a peekstack)
PLAYER_PATH_NODE LAYER::UnlayPath( int nLayers )
{
	// unwind to, and including this current spot.
	// this is to handle when the line intersects itself.
	// other conditions of unlaying via pathways may require
	// other functionality.
	int n;
	PLAYER_PATH_NODE node;// = (PLAYER_PATH_NODE)PopData( &pds_path );
	lprintf( WIDE("overlapped self at path segment %d"), nLayers );
	for( n = nLayers; (n && (node = (PLAYER_PATH_NODE)PopData( &pds_path ))), n; n-- )
	{
		lprintf( WIDE("Popped node %d(%p)"), n, node );
		// grab the NEXT node...
		// if it has bForced set... then this node must exist.
		PLAYER_PATH_NODE next = (PLAYER_PATH_NODE)PeekData( &pds_path );
		if( next && next->flags.bForced )
		{
			DebugBreak();
			node->flags.ForeDir = NOWHERE;
			return node;
		}
		if( node && node->flags.bForced )
		{
			DebugBreak();
         // this is SO bad.
		}
		//if( node->x == dest_x && node->y == dest_y )
		{
			//lprintf( WIDE("And then we find the node we overlaped...") );
		}
	}
	lprintf( WIDE("Okay done popping... %d, %p"), n, node );
	if( node )
	{
		PLAYER_PATH_NODE next = (PLAYER_PATH_NODE)PeekData( &pds_path );
		// set this as nowhere, so that we can easily just step forward here..
		if( !next )
		{
			if( !node->flags.bForced )
			{
				node->flags.ForeDir = NOWHERE;
			}
			PushData( &pds_path, node );
			return node;
		}
		if( !nLayers
			&& next->flags.bForced
			&& next->flags.BackDir != NOWHERE )
		{
			// if it was forced, then this MUST be here.  There is a reason.
			// there is also a way to end this reason, and unlay 0 path.  This
			// releases the foredir to anything.  This may be used for error correction path
			// assumptions?
			DebugBreak();
			if( next->flags.bTry )
			{
				node = (PLAYER_PATH_NODE)PopData(&pds_path );
				// this is the second attempt
				if( !node->flags.bFlopped )
				{
					node->flags.bFlopped = 1;
					node->flags.ForeDir = LeftOrRight( Opposite( node->flags.BackDir ), 1 );
               return node;
				}
			}
			next->flags.bForced = 0;
		}
		else
		{
			next->flags.ForeDir = NOWHERE;
         lprintf( WIDE("this node itself is okay...") );
		}
      return next;
	}
   return NULL;
}
Exemplo n.º 4
0
void LAYER::LayPath( int32_t wX, int32_t wY )
{
	int DeltaDir;
	LOGICAL bLoop = FALSE, bIsRetry;  // no looping....
	int tx, ty;
	int nPathLayed = 0;
	int nDir, nNewDir;
	LOGICAL bBackTrace = FALSE,
		bFailed = FALSE;

	PLAYER_PATH_NODE node;
	lprintf( WIDE("Laying path %p to %d,%d"), this, wX, wY );
	node = (PLAYER_PATH_NODE)PeekData( &pds_path );
	// sanity validations...
	// being done already, etc...
	wX -= LAYER::x;
	wY -= LAYER::y;
	if( node )
	{
		if( node->x == wX && node->y == wY )
		{
			lprintf( WIDE("Already at this end point, why are you telling me to end where I already did?") );
			return;
		}
		// should range check wX and wY to sane limits
		// but for now we'll trust the programmer...
		if( abs( node->x - wX ) > 100 || abs( node->y - wY ) > 100 )
		{
			DebugBreak();
			lprintf( WIDE("Laying a LONG path - is this okay?!") );
		}
	}

	#ifdef DEBUG_BACKTRACE
		Log( WIDE("Enter...") );
	#endif

		//------------ FORWARD DRAWING NOW .....
	bIsRetry = FALSE;
	DeltaDir = 0;
	{
		PLAYER_PATH_NODE node;
		// get the last node in the path.
		node = (PLAYER_PATH_NODE)PeekData( &pds_path );
		while( node )
		{
			nNewDir = FindDirection( node->x
										  , node->y
										  , wX, wY );
			if( nNewDir == NOWHERE )
			{
				// already have this node at the current spot...
				lprintf( WIDE("Node has ended here...") );
				break;
			}
			nDir = NOWHERE; // intialize this, in case we missed a path below...
			if( node->flags.BackDir == NOWHERE )
			{
				// if it is newdir, we're okay to go ahead with this plan.
				if( node->flags.ForeDir != nNewDir && flags.bForced )
				{
					lprintf( WIDE("Have a forced begin point, and no way to get there from here....") );
					DebugBreak();
					if( NearDir( node->flags.ForeDir, nNewDir ) == 10 )
					{
						lprintf( WIDE("MUST go %d , have to go %d from here.  Go nowhere."), node->flags.ForeDir, nNewDir );
						lprintf( WIDE("Okay - consider a arbitrary jump to go forward... until we can go backward.") );
					}
					else
					{
						lprintf( WIDE("It's just not quite right... return, a less radical assumption may be made.") );
					}
					return;
				}
				// else, just go ahead, we returned above here.
				node->flags.ForeDir = nNewDir;
			}
			else
			{
				// need to determine a valid foredir based on nNewDir desire, and nBackDir given.
				lprintf( WIDE("%d, %d = %d")
						 , Opposite( node->flags.BackDir )
						 , nNewDir
						 , NearDir(Opposite( node->flags.BackDir )
									 , nNewDir ) );
				lprintf( WIDE("newdir = %d backdir = %d"), nNewDir, node->flags.BackDir );
				//pold->TopLayer->ForeDir;
				if( NearDir( nNewDir, Opposite( node->flags.BackDir ) ) != 10 )
				{
					// this is a valid direction to go.
					node->flags.ForeDir = nNewDir;
				}
				else
				{
					lprintf( WIDE("Unlay path cause we can't get there from here.") );
					node = UnlayPath( nPathLayed + 1 );
					// at this point always unlay at least one more than we put down.
					nPathLayed = 1;
					continue;
#if 0
               int nBase = Opposite( node->flags.BackDir );
					nDir = ( node->flags.BackDir + 2 ) & 7;
					if( NearDir( nNewDir, nDir ) != 10 )
					{
						//node->flags.ForeDir = (nBase + 6) &7;
						node->flags.ForeDir = Right( nBase );
					}
					else if( NearDir( nNewDir, Opposite( nDir ) ) != 10 )
					{
						node->flags.ForeDir = Left(nBase);
					}
					else
					{

						// this should be a random chance to go left or right...
						// maybe tend to the lower x or higher x ?
						lprintf( WIDE("Choosing an arbitrary directino of 1, and only on1") );
						//node->flags.ForeDir = Right( nBase + 1 );
						node->flags.bFlopped = 0;
						node->flags.bTry = 1;
						node->flags.bForced = 1;
						node->flags.ForeDir = LeftOrRight( nBase, node->flags.bFlopped );
						// set a flag in this node for which way to go...
						// but a left/right node needs the ability
						// to remain forced for a single unlay, and move in a direction...

					}
#endif
				}
			}
			{
				int  n;
				tx = node->x + DirDeltaMap[node->flags.ForeDir].x;
				ty = node->y + DirDeltaMap[node->flags.ForeDir].y;
				lprintf( WIDE("New coordinate will be %d,%d"), tx, ty );
				if( n = Overlaps( tx, ty ) ) // aleady drew something here...
					// the distance of the overlap is n layers, including Nth layer
					// for( ; n; PopData(&pds_stack), n-- )
					// and some fixups which unlay path does.
				{
					lprintf( WIDE("Unlaying path %d steps to overlap") , n );
					node = UnlayPath( n );
					// at an unlay point of forced, unlay path should be 'smart' and 'wait'
					// otherwise we may unwind to our tail and be confused... specially when moving away
					// and coming back to reside at the center.
					// if the force direction to go from a forced node is excessive, that definatly
					// breaks force, and releases the path node.
					// there may be board conditions which also determine the pathing.
					// okay try this again from the top do {
					// startin laying path again.
					continue;
				}
				// otherwise we're good to go foreward.
				// at least we won't add this node if it would have
				// already been there, heck, other than that via's
				// don't exist, sometimes we'll even get the exact node
				// that this should be....
				{
					LAYER_PATH_NODE newnode;
					// this may be set intrinsically by being an excessive force
					// causing a large direction delta
					newnode.flags.bForced = FALSE;
					newnode.flags.ForeDir = NOWHERE;
					// this of course must start(?) exactly how the other ended(?)...
					newnode.flags.BackDir = Opposite( node->flags.ForeDir );
					newnode.x = tx;
					newnode.y = ty;
					{
						int xx = tx + x;
						int yy = ty + y;
						if( xx < min_x )
						{
							w += min_x - xx;
							min_x = xx;
						}
						if( xx >= ( min_x + (int32_t)w ) )
							w = xx - min_x + 1;
						if( yy < min_y )
						{
							h += min_y - yy;
							min_y = yy;
						}
						if( yy >= ( min_y + (int32_t)h ) )
							h = yy - min_y + 1;

					}
					lprintf( WIDE("Push path %d,%d  min=%d,%d size=%d,%d"), newnode.x, newnode.y, min_x, min_y, w, h );
					PushData( &pds_path, &newnode );
					nPathLayed++;
					node = (PLAYER_PATH_NODE)PeekData( &pds_path ); // okay this is now where we are.
				}
			}
		}
	}
}
Exemplo n.º 5
0
void
dedtype(RING * gbl,
	char *name,
	int inlist,
	int binary,
	int stripped,
	int isdir)
{
    int had_eof;
    int c;
    int count,			/* ...and repeat-count */
      y,			/* current line-in-screen */
      shift = COLS / 4,		/* amount of left/right shift */
      done = FALSE, shown = FALSE, infile = -1;		/* # of lines processed */
    OFF_T skip = 0;

    tabstop = 8;
    Shift = 0;
    UsePattern = FALSE;
    OptBinary = binary;
    OptStripped = stripped;

    if (isdir && !OptBinary) {
	DIR *dp;
	DirentT *de;
	char bfr[MAXPATHLEN];
# define INO_FMT "%5lu"
	if ((InFile = tmpfile()) == 0) {
	    warn(gbl, "tmp-file");
	    return;
	}
	if ((dp = opendir(name)) != 0) {
	    while ((de = readdir(dp)) != NULL) {
		(void) ded2string(gbl, bfr,
				  (int) NAMLEN(de),
				  de->d_name,
				  FALSE);
		FPRINTF(InFile, INO_FMT, (unsigned long) de->d_ino);
		FPRINTF(InFile, " %s\n", bfr);
	    }
	    (void) closedir(dp);
	    rewind(InFile);
	} else {
	    warn(gbl, "opendir");
	    FCLOSE(InFile);
	    return;
	}
    } else
	InFile = fopen(name, "r");

    in_dedtype = TRUE;		/* disable clearing of workspace via A/a cmd */

    if (InFile) {
	int jump = 0;

	dlog_comment("type \"%s\" (%s %s)\n",
		     name,
		     OptBinary ? "binary" : "text",
		     isdir ? "directory" : "file");
	to_work(gbl, FALSE);

	dyn_init(&my_text, BUFSIZ);
	dyn_init(&my_over, BUFSIZ);

	max_lines = -1;
	MarkLine(&infile);

	while (!done) {

	    if (jump) {
#if defined(HAVE_WSCRL) && defined(HAVE_WSETSCRREG)
		/*
		 * If we're doing single-line scrolling past
		 * the point we've read in the file, try to
		 * cache pointers so that the scrolling logic
		 * will go more smoothly.
		 */
		if (jump > 0
		    && jump < NumP(1)
		    && infile + NumP(1) >= max_lines) {
		    int line = infile;
		    (void) StartPage(&line, TRUE, &had_eof);
		}
#endif
		(void) JumpBackwards(&infile, jump);
		jump = 0;
	    }

	    markC(gbl, TRUE);
	    y = StartPage(&infile, (int) skip, &had_eof);
	    if (skip && !was_interrupted) {
		if (feof(InFile)) {
		    skip = 0;
		    jump = NumP(1);
		} else {
		    IgnorePage(infile);
		    skip--;
		}
		continue;
	    }
	    if (had_eof) {
		int blank;
		infile = TopOfPage(infile, &blank);
		(void) JumpToLine(infile);
		y = StartPage(&infile, 0, &had_eof);
	    }
	    shown |= FinishPage(gbl, inlist, infile, y);
	    jump = NumP(1);

	    reset_catcher();
	    switch (c = dlog_char(gbl, &count, 1)) {
	    case CTL('K'):
		deddump(gbl);
		break;
	    case 'w':
		retouch(gbl, 0);
		break;
	    case '\t':
		if (OptBinary) {
		    beep();
		} else {
		    tabstop = (count <= 1)
			? (tabstop == 8 ? 4 : 8)
			: count;
		}
		break;

	    case 'q':
		done = TRUE;
		break;

	    case KEY_HOME:
	    case '^':
		jump = infile;
		break;

	    case KEY_END:
	    case '$':
		infile = max_lines;
		skip = MaxP();
		break;

	    case KEY_PPAGE:
	    case '\b':
	    case 'b':
		if (AtTop(infile)) {
		    beep();
		} else {
		    jump += NumP(count);
		}
		break;
	    case KEY_NPAGE:
	    case '\n':
	    case ' ':
	    case 'f':
		jump = 0;
		skip = count - 1;
		break;

	    case '<':
	    case CTL('L'):
		LeftOrRight(-shift * count);
		break;
	    case '>':
	    case CTL('R'):
		LeftOrRight(shift * count);
		break;

	    case KEY_LEFT:
	    case 'h':
		LeftOrRight(-count);
		break;
	    case KEY_DOWN:
	    case 'j':
		jump = NumP(1) - count;
		if ((infile - jump) > max_lines) {
		    skip = (-jump + NumP(1) - 1) / NumP(1);
		    jump = 0;
		}
		break;
	    case KEY_UP:
	    case 'k':
		if (AtTop(infile)) {
		    beep();
		} else {
		    jump += count;
		}
		break;
	    case KEY_RIGHT:
	    case 'l':
		LeftOrRight(count);
		break;

		/* move work-area marker */
	    case 'A':
		count = -count;
		jump -= count;
		/*FALLTHRU */
	    case 'a':
		markset(gbl, (unsigned) (mark_W + count));
		break;

	    case '/':
	    case '?':
	    case 'n':
	    case 'N':
		FindPattern(gbl, &infile, c);
		break;
	    default:
		beep();
	    }
	}
	FCLOSE(InFile);
	if (shown)
	    (void) reshow(gbl, (unsigned) inlist);
	showMARK(gbl->Xbase);

	showC(gbl);
    } else
	warn(gbl, name);
    in_dedtype = FALSE;
}