Ejemplo n.º 1
0
hEntity GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
    // Save the original endpoints, since we're about to delete this entity.
    Entity *e01 = SK.GetEntity(he);
    hEntity hep0 = e01->point[0], hep1 = e01->point[1];
    Vector p0 = SK.GetEntity(hep0)->PointGetNum(),
           p1 = SK.GetEntity(hep1)->PointGetNum();

    // Add the two line segments this one gets split into.
    hRequest r0i = AddRequest(Request::LINE_SEGMENT, false),
             ri1 = AddRequest(Request::LINE_SEGMENT, false);
    // Don't get entities till after adding, realloc issues

    Entity *e0i = SK.GetEntity(r0i.entity(0)),
           *ei1 = SK.GetEntity(ri1.entity(0));

    SK.GetEntity(e0i->point[0])->PointForceTo(p0);
    SK.GetEntity(e0i->point[1])->PointForceTo(pinter);
    SK.GetEntity(ei1->point[0])->PointForceTo(pinter);
    SK.GetEntity(ei1->point[1])->PointForceTo(p1);

    ReplacePointInConstraints(hep0, e0i->point[0]);
    ReplacePointInConstraints(hep1, ei1->point[1]);
    Constraint::ConstrainCoincident(e0i->point[1], ei1->point[0]);
    return e0i->point[1];
}
Ejemplo n.º 2
0
static int CreateRandomStrategyRequests(GDALDataset* poDS,
                                        int nMaxRequests,
                                        Request*& psRequestList,
                                        Request*& psRequestLast)
{
    unsigned long seed = 1;
    int nXSize = poDS->GetRasterXSize();
    int nYSize = poDS->GetRasterYSize();
    int nMaxXWin = MIN(1000, nXSize/10+1);
    int nMaxYWin = MIN(1000, nYSize/10+1);
    int nQueriedBands = MIN(4, poDS->GetRasterCount());
    int nAverageIterationsToReadWholeFile =
        ((nXSize + nMaxXWin/2-1) / (nMaxXWin/2)) * ((nYSize + nMaxYWin/2-1) / (nMaxYWin/2));
    int nLocalLoops = nLoops * nAverageIterationsToReadWholeFile;
    for(int iLoop=0;iLoop<nLocalLoops;iLoop++)
    {
        if( nMaxRequests > 0 && iLoop == nMaxRequests )
            break;
        int nXOff = (int)((GIntBig)myrand_r(&seed) * (nXSize-1) / MYRAND_MAX);
        int nYOff = (int)((GIntBig)myrand_r(&seed) * (nYSize-1) / MYRAND_MAX);
        int nXWin = 1+(int)((GIntBig)myrand_r(&seed) * nMaxXWin / MYRAND_MAX);
        int nYWin = 1+(int)((GIntBig)myrand_r(&seed) * nMaxYWin / MYRAND_MAX);
        if( nXOff + nXWin > nXSize )
            nXWin = nXSize - nXOff;
        if( nYOff + nYWin > nYSize )
            nYWin = nYSize - nYOff;
        AddRequest(psRequestList, psRequestLast, nXOff, nYOff, nXWin, nYWin, nQueriedBands);
    }
    return nQueriedBands * nMaxXWin * nMaxYWin;
}
Ejemplo n.º 3
0
static int CreateBlockStrategyRequests(GDALDataset* poDS,
                                       int nMaxRequests,
                                       Request*& psRequestList,
                                       Request*& psRequestLast)
{
    int nXSize = poDS->GetRasterXSize();
    int nYSize = poDS->GetRasterYSize();
    int nMaxXWin = MIN(1000, nXSize/10+1);
    int nMaxYWin = MIN(1000, nYSize/10+1);
    int nQueriedBands = MIN(4, poDS->GetRasterCount());
    int bStop = FALSE;
    int nRequests = 0;
    for(int iLoop=0;!bStop && iLoop<nLoops;iLoop++)
    {
        for(int nYOff=0;!bStop && nYOff<nYSize;nYOff+=nMaxYWin)
        {
            int nReqYSize = (nYOff + nMaxYWin > nYSize) ? nYSize - nYOff : nMaxYWin;
            for(int nXOff=0;nXOff<nXSize;nXOff+=nMaxXWin)
            {
                if( nMaxRequests > 0 && nRequests == nMaxRequests )
                {
                    bStop = TRUE;
                    break;
                }
                int nReqXSize = (nXOff + nMaxXWin > nXSize) ? nXSize - nXOff : nMaxXWin;
                AddRequest(psRequestList, psRequestLast, nXOff, nYOff, nReqXSize, nReqYSize, nQueriedBands);
                nRequests ++;
            }
        }
    }
    return nQueriedBands * nMaxXWin * nMaxYWin;
}
Ejemplo n.º 4
0
static int CreateLineStrategyRequests(GDALDataset* poDS,
                                      int nMaxRequests,
                                      Request*& psRequestList,
                                      Request*& psRequestLast)
{
    int nXSize = poDS->GetRasterXSize();
    int nYSize = poDS->GetRasterYSize();
    int nQueriedBands = MIN(4, poDS->GetRasterCount());
    int bStop = FALSE;
    int nRequests = 0;
    for(int iLoop=0;!bStop && iLoop<nLoops;iLoop++)
    {
        for(int nYOff=0;nYOff<nYSize;nYOff++)
        {
            if( nMaxRequests > 0 && nRequests == nMaxRequests )
            {
                bStop = TRUE;
                break;
            }
            AddRequest(psRequestList, psRequestLast, 0, nYOff, nXSize, 1, nQueriedBands);
            nRequests ++;
        }
    }
    return nQueriedBands * nXSize;
}
Ejemplo n.º 5
0
int KernelService::RequestProcessExec(const char* szFile, int iNoOfArgs, const char** szArgs)
{
	char szProcessPath[128] ;
	char szFullProcPath[128] ;
	
	if(String_Chr(szFile, '/') < 0)
	{
		if(!GenericUtil_GetFullFilePathFromEnv(PATH_ENV, BIN_PATH, szFile, szProcessPath))
		{
			return -2 ;
		}

		strcpy(szFullProcPath, szProcessPath) ;
		strcat(szFullProcPath, szFile) ;
	}
	else
	{
		strcpy(szFullProcPath, szFile) ;
	}
	
	KernelService::ProcessExec* pRequest = new KernelService::ProcessExec(iNoOfArgs, szFullProcPath, szArgs) ;

	AddRequest(pRequest) ;
	ProcessManager::Instance().WaitOnKernelService() ;

	int iNewProcId = pRequest->GetNewProcId() ;

	delete pRequest ;

	return iNewProcId ;
}
Ejemplo n.º 6
0
hEntity GraphicsWindow::SplitCircle(hEntity he, Vector pinter) {
    Entity *circle = SK.GetEntity(he);
    if(circle->type == Entity::CIRCLE) {
        // Start with an unbroken circle, split it into a 360 degree arc.
        Vector center = SK.GetEntity(circle->point[0])->PointGetNum();

        circle = NULL; // shortly invalid!
        hRequest hr = AddRequest(Request::ARC_OF_CIRCLE, false);

        Entity *arc = SK.GetEntity(hr.entity(0));

        SK.GetEntity(arc->point[0])->PointForceTo(center);
        SK.GetEntity(arc->point[1])->PointForceTo(pinter);
        SK.GetEntity(arc->point[2])->PointForceTo(pinter);

        Constraint::ConstrainCoincident(arc->point[1], arc->point[2]);
        return arc->point[1];
    } else {
        // Start with an arc, break it in to two arcs
        hEntity hc = circle->point[0],
                hs = circle->point[1],
                hf = circle->point[2];
        Vector center = SK.GetEntity(hc)->PointGetNum(),
               start  = SK.GetEntity(hs)->PointGetNum(),
               finish = SK.GetEntity(hf)->PointGetNum();

        circle = NULL; // shortly invalid!
        hRequest hr0 = AddRequest(Request::ARC_OF_CIRCLE, false),
                 hr1 = AddRequest(Request::ARC_OF_CIRCLE, false);

        Entity *arc0 = SK.GetEntity(hr0.entity(0)),
               *arc1 = SK.GetEntity(hr1.entity(0));

        SK.GetEntity(arc0->point[0])->PointForceTo(center);
        SK.GetEntity(arc0->point[1])->PointForceTo(start);
        SK.GetEntity(arc0->point[2])->PointForceTo(pinter);

        SK.GetEntity(arc1->point[0])->PointForceTo(center);
        SK.GetEntity(arc1->point[1])->PointForceTo(pinter);
        SK.GetEntity(arc1->point[2])->PointForceTo(finish);

        ReplacePointInConstraints(hs, arc0->point[1]);
        ReplacePointInConstraints(hf, arc1->point[2]);
        Constraint::ConstrainCoincident(arc0->point[2], arc1->point[1]);
        return arc0->point[2];
    }
}
Ejemplo n.º 7
0
bool KernelService::RequestPageFault(unsigned uiFaultyAddress)
{
	KernelService::PageFault* pRequest = new KernelService::PageFault(uiFaultyAddress) ;

	AddRequest(pRequest) ;
	ProcessManager::Instance().WaitOnKernelService() ;

	bool bStatus = pRequest->GetStatus() ;
	delete pRequest ;
	return bStatus ;
}
Ejemplo n.º 8
0
int TransferQueueManager::HandleRequest(int cmd,Stream *stream)
{
	ReliSock *sock = (ReliSock *)stream;
	ASSERT( cmd == TRANSFER_QUEUE_REQUEST );

	ClassAd msg;
	sock->decode();
	if( !getClassAd( sock, msg ) || !sock->end_of_message() ) {
		dprintf(D_ALWAYS,
				"TransferQueueManager: failed to receive transfer request "
				"from %s.\n", sock->peer_description() );
		return FALSE;
	}

	bool downloading = false;
	MyString fname;
	MyString jobid;
	MyString queue_user;
	filesize_t sandbox_size;
	if( !msg.LookupBool(ATTR_DOWNLOADING,downloading) ||
		!msg.LookupString(ATTR_FILE_NAME,fname) ||
		!msg.LookupString(ATTR_JOB_ID,jobid) ||
		!msg.LookupString(ATTR_USER,queue_user) ||
		!msg.LookupInteger(ATTR_SANDBOX_SIZE,sandbox_size))
	{
		MyString msg_str;
		sPrintAd(msg_str, msg);
		dprintf(D_ALWAYS,"TransferQueueManager: invalid request from %s: %s\n",
				sock->peer_description(), msg_str.Value());
		return FALSE;
	}

		// Currently, we just create the client with the default max queue
		// age.  If it becomes necessary to customize the maximum age
		// on a case-by-case basis, it should be easy to adjust.

	TransferQueueRequest *client =
		new TransferQueueRequest(
			sock,
			sandbox_size,
			fname.Value(),
			jobid.Value(),
			queue_user.Value(),
			downloading,
			m_default_max_queue_age);

	if( !AddRequest( client ) ) {
		delete client;
		return KEEP_STREAM; // we have already closed this socket
	}

	return KEEP_STREAM;
}
STDMETHODIMP CHyperFeedPriceInfoWithNotify::RequestLastQuote(QuoteUpdateParams *Params)
{
	ATLTRACE(_T("CHyperFeedPriceInfoWithNotify::RequestLastQuote\n"));
	try
	{
		CRequestBasePtr pRequest = CRequestBasePtr((CRequestBase*)new CQuoteRequest(_enRequestLast, Params));
		AddRequest(pRequest);
	}
	_CATCH_COM_EXCEPTION_RETURN_COM( L"RequestLastQuote Failed")
	_CATCH_UNHANDLED_EXCEPTION_RETURN_COM;
	return S_OK;
}
BOOL CUploadTransferED2K::OnRequestParts(CEDPacket* pPacket)
{
	if ( pPacket->GetRemaining() < sizeof(MD4) + 4 * 3 * 2 )
	{
		theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
		Close();
		return FALSE;
	}
	
	MD4 pMD4;
	pPacket->Read( &pMD4, sizeof(MD4) );
	
	if ( pMD4 != m_pED2K )
	{
		if ( ! Request( &pMD4 ) ) return FALSE;
	}
	
	if ( m_nState != upsQueued && m_nState != upsRequest && m_nState != upsUploading )
	{
		theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
		Close();
		return FALSE;
	}
	
	DWORD nOffset[2][3];
	pPacket->Read( nOffset, sizeof(DWORD) * 2 * 3 );
	
	for ( int nRequest = 0 ; nRequest < 3 ; nRequest++ )
	{
		if ( nOffset[1][nRequest] <= m_nFileSize )
		{
			// Valid (or null) request
			if ( nOffset[0][nRequest] < nOffset[1][nRequest] )
			{
				// Add non-null ranges to the list
				AddRequest( nOffset[0][nRequest], nOffset[1][nRequest] - nOffset[0][nRequest] );
			}
		}
		else
		{
			// Invalid request- had an impossible range.
			theApp.Message( MSG_ERROR, _T("Invalid file range(s) in request from %s"), (LPCTSTR)m_sAddress );
			// They probably have an incorrent hash associated with a file. Calling close now
			// will send "file not found" to stop them re-asking, then close the connection.
			Close();
			return FALSE;
		}
	}
	
	ServeRequests();
	
	return TRUE;
}
Ejemplo n.º 11
0
unsigned KernelService::RequestFlatAddress(unsigned uiVirtualAddress)
{
	KernelService::FlatAddress* pRequest = new KernelService::FlatAddress(uiVirtualAddress) ;
	AddRequest(pRequest) ;

	ProcessManager::Instance().WaitOnKernelService() ;

	unsigned uiFlatAddress = pRequest->GetFlatAddress() ;

	delete pRequest ;

	return uiFlatAddress ;
}
Ejemplo n.º 12
0
bool KernelService::RequestDLLAlloCopy(int iDLLEntryIndex, unsigned uiAllocPageCnt, unsigned uiNoOfPages)
{
	KernelService::DLLAllocCopy* pRequest = new KernelService::DLLAllocCopy(iDLLEntryIndex, uiAllocPageCnt, uiNoOfPages) ;
	AddRequest(pRequest) ;

	ProcessManager::Instance().WaitOnKernelService() ;

	bool bStatus = pRequest->GetStatus() ;

	delete pRequest ;

	return bStatus ;
}
STDMETHODIMP CHyperFeedStructureProviderEx::RequestFuture(FutureParams *Params)
{
	try
	{ 
		CRequestBasePtr pRequest = CRequestBasePtr((CRequestBase*)new CFutureRequest(Params));
		AddRequest(pRequest);
	}
	catch (_com_error &err)
	{
		return EgLib::utils::ComError2ErrInfo (err,this);
	}
	return S_OK;
}
STDMETHODIMP CHyperFeedStructureInfo::RequestOptions(OptionParams *Params)
{
	try
	{ 
		CRequestBasePtr pRequest = CRequestBasePtr((CRequestBase*)new COptionRequest(Params));
		AddRequest(pRequest);
	}
	catch (_com_error &err)
	{
		return EgLib::utils::ComError2ErrInfo (err,this);
	}
	return S_OK;
}
STDMETHODIMP CHyperFeedStructureProviderEx::RequestFuturesOptions(FuturesOptionParams *Params)
{
	try
	{ 
		CRequestBasePtr pRequest = boost::shared_static_cast<CRequestBase>(CFuturesOptionRequestPtr(new CFuturesOptionRequest(Params)));
		AddRequest(pRequest);
	}
	catch (_com_error &err)
	{
		return EgLib::utils::ComError2ErrInfo (err,this);
	}
	return S_OK;
}
Ejemplo n.º 16
0
/////////////////////////////////////////////////////////////////////////////
// CHyperFeedPriceProvider
STDMETHODIMP CHyperFeedPriceProvider::RequestLastQuote(QuoteUpdateParams *Params)
{
	try
	{
		CRequestBasePtr pRequest = CRequestBasePtr((CRequestBase*)new CQuoteRequest(_enRequestLast, Params));
		AddRequest(pRequest);
	}
	catch (_com_error &err)
	{
		return EgLib::utils::ComError2ErrInfo (err,this);
	}
	return S_OK;
}
STDMETHODIMP CHyperFeedStructureProviderEx::RequestStock(StockParams *Params)
{
	try
	{
		CRequestBasePtr pRequest = CRequestBasePtr((CRequestBase*)new CStockRequest(Params));
		EgStd::CEgTracingClass::TraceStatic(enlogInfo, __FUNCTION__ , CW2T(Params->Stock));
		AddRequest(pRequest);
	}
	catch (_com_error &err)
	{
		return EgLib::utils::ComError2ErrInfo (err,this);
	}
	return S_OK;
}
Ejemplo n.º 18
0
STDMETHODIMP CHyperFeedPriceInfoWithNotify::RequestLastGroupQuotes(QuoteUpdateParams * Params)
{
	try
	{
		if(Params->Type != enGrSTK && Params->Type != enGrIDX)
			return E_INVALIDARG;

		CRequestBasePtr pRequest = CRequestBasePtr((CRequestBase*)new CGroupRequest(enGroupRequestLastQuote, Params));
		AddRequest(pRequest);
	}
	_CATCH_COM_EXCEPTION_RETURN_COM( L"RequestLastGroupQuotes Failed")
	_CATCH_UNHANDLED_EXCEPTION_RETURN_COM;
	return S_OK;
}
Ejemplo n.º 19
0
bool CDSISession::Open(const char* pHostName, unsigned int port, unsigned int timeout /*=3000*/)
{
  XAFP_LOG(XAFP_LOG_FLAG_INFO, "DSI Protocol: Opening session for %s:%d", pHostName, port);

  if (!GetStatus(pHostName, port, m_ServerInfo))
    return false; // Report's its own errors
  
  if (!Connect(pHostName, port, (ITCPReceiveCallback*)this, timeout))
    return false; // Report's its own errors

  CDSIBuffer reqBuf(6);
  reqBuf.Write((uint8_t)0x01);  // Session Option Type (Attention Quantum)
  reqBuf.Write((uint8_t)4);     // Option Data Size
  reqBuf.Write((uint32_t)1024); // Option Value
  
  // Add Request to map so receive handler can notify us
  CDSIBuffer response; // TODO: Remove this once the handler is able to ignore payloads
  CDSISyncRequest req(GetNewRequestId(), &response);
  AddRequest(&req);

  int err = SendMessage(DSIOpenSession, req.GetId(), &reqBuf); // Report's its own errors
  if (!err)
  {
    // The request went out, now wait for a reply
    err = req.Wait();
    if (!err)
    {
      XAFP_LOG(XAFP_LOG_FLAG_INFO, "DSI Protocol: Opened session for %s:%d", pHostName, port);
      m_IsOpen = true;
    }
    else
    {
      XAFP_LOG(XAFP_LOG_FLAG_ERROR, "DSI Protocol: Failed to open session for %s:%d. Error: %d", pHostName, port, err);
    }
  }
  else if (err == kTCPSendError)
  {
    // Something went wrong while sending the request
    XAFP_LOG(XAFP_LOG_FLAG_ERROR, "DSI Protocol: TCP error while sending session request to %s:%d. Error: %d", pHostName, port, err);
    // TODO: Do we want to do this?
    Disconnect();
  }
  else
  {
    XAFP_LOG(XAFP_LOG_FLAG_ERROR, "DSI Protocol: An error occurred while sending session request to %s:%d. Error: %d", pHostName, port, err);
  }
  
  return (!err);
}
STDMETHODIMP CHyperFeedStructureProviderEx::RequestOptions(OptionParams *Params)
{
	try
	{ 
		CRequestBasePtr pRequest = CRequestBasePtr((CRequestBase*)new COptionRequest(Params));
		EgLib::CEgLibTraceManager::Trace(LogInfo, __FUNCTION__ , CW2T(Params->UnderlyingSymbol));

		AddRequest(pRequest);
	}
	catch (_com_error &err)
	{
		return EgLib::utils::ComError2ErrInfo (err, this);
	}
	return S_OK;
}
Ejemplo n.º 21
0
STDMETHODIMP CHyperFeedPriceProvider::RequestGroup(QuoteUpdateParams * Params,  GroupRequestType enOperationType)
{
	try
	{
		if(Params->Type != enGrSTK && Params->Type != enGrIDX && Params->Type != enSTK && Params->Type != enIDX)
			return E_INVALIDARG;

		CRequestBasePtr pRequest = CRequestBasePtr((CRequestBase*)new CGroupRequest(enOperationType, Params));
		AddRequest(pRequest);
	}
	catch (_com_error &err)
	{
		return EgLib::utils::ComError2ErrInfo (err,this);
	}
	return S_OK;
}
Ejemplo n.º 22
0
int32_t CDSISession::SendCommandAsync(CDSIBuffer& payload, CDSIAsyncCallback* pCallback, uint32_t writeOffset /*=0*/)
{
  if (!IsOpen())
  {
    XAFP_LOG_0(XAFP_LOG_FLAG_ERROR, "DSI Protocol: Attempting to use closed session");
    return kDSISessionClosed;
  }
  
  // The DSICommand message always expects a response, even if the caller does not (no return payload)
  if (!pCallback)
  {
    XAFP_LOG_0(XAFP_LOG_FLAG_ERROR, "DSI Protocol: Invalid callback passed to SendCommandAsync()");
    return kFPParamErr;
  }
  
  // Async Request handling
  CDSIAsyncRequest* pReq =  new CDSIAsyncRequest(GetNewRequestId(), pCallback); // This object will self-destruct upon completion
  if (!AddRequest(pReq)) // Add Request to map so receive handler can notify us (do this before calling SendMessage, to make sure it is there in time)
  {
    // This really should not happen...ever
    delete pReq;
    return kFPParamErr;
  }
  
  // TODO: This is a messy way to get the AFP command Id...
  XAFP_LOG(XAFP_LOG_FLAG_DSI_PROTO, "DSI Protocol: Sending async command (%s), requestId: %d", AFPProtoCommandToString(*((uint8_t*)payload.GetData())), pReq->GetId());
  
  int err = kNoError;
  if (writeOffset)
  {
    err = SendMessage(DSIWrite, pReq->GetId(), &payload, writeOffset);
  }
  else
  {
    err = SendMessage(DSICommand, pReq->GetId(), &payload);
  }
  
  if (err)
  {
    XAFP_LOG(XAFP_LOG_FLAG_ERROR, "DSI Protocol: Failed to send async command (%s), requestId: %d, result: %d", AFPProtoCommandToString(*((uint8_t*)payload.GetData())), pReq->GetId(), err);
    delete pReq; // This will also clean-up the callback (closure) object
  }
  return err;
}
Ejemplo n.º 23
0
int32_t CDSISession::SendCommand(CDSIBuffer& payload, CDSIBuffer* pResponse /*=NULL*/, uint32_t writeOffset /*=0*/)
{
  if (!IsOpen())
  {
    XAFP_LOG_0(XAFP_LOG_FLAG_ERROR, "DSI Protocol: Attempting to use closed session");
    return kDSISessionClosed;
  }
  
// Sync Request handling  
  CDSISyncRequest req(GetNewRequestId(), pResponse);
  AddRequest(&req); // Add Request to map so receive handler can notify us
  
  // TODO: This is a messy way to get the AFP command Id...
  XAFP_LOG(XAFP_LOG_FLAG_DSI_PROTO, "DSI Protocol: Sending command (%s), requestId: %d", AFPProtoCommandToString(*((uint8_t*)payload.GetData())), req.GetId());

  int err = kNoError;
  if (writeOffset)
  {
    err = SendMessage(DSIWrite, req.GetId(), &payload, writeOffset);
  }
  else
  {
    err = SendMessage(DSICommand, req.GetId(), &payload);
  }
  
  if (!err)
  {
    // The DSICommand message always expects a response, even if the caller does not (no return payload)
    // Wait for the response and return the result to the caller
    return req.Wait();
  }
  else
  {
    // TODO: This is a messy way to get the AFP command Id...
    XAFP_LOG(XAFP_LOG_FLAG_ERROR, "DSI Protocol: Failed to send command (%s), requestId: %d, result: %d", AFPProtoCommandToString(*((uint8_t*)payload.GetData())), req.GetId(), err);
  }
  
  return err;
}
Ejemplo n.º 24
0
void GraphicsWindow::MouseLeftDown(double mx, double my) {
    orig.mouseDown = true;

    if(GraphicsEditControlIsVisible()) {
        orig.mouse = Point2d::From(mx, my);
        orig.mouseOnButtonDown = orig.mouse;
        HideGraphicsEditControl();
        return;
    }
    SS.TW.HideEditControl();

    if(SS.showToolbar) {
        if(ToolbarMouseDown((int)mx, (int)my)) return;
    }

    // Make sure the hover is up to date.
    MouseMoved(mx, my, false, false, false, false, false);
    orig.mouse.x = mx;
    orig.mouse.y = my;
    orig.mouseOnButtonDown = orig.mouse;

    // The current mouse location
    Vector v = offset.ScaledBy(-1);
    v = v.Plus(projRight.ScaledBy(mx/scale));
    v = v.Plus(projUp.ScaledBy(my/scale));

    hRequest hr;
    switch(pending.operation) {
        case MNU_DATUM_POINT:
            hr = AddRequest(Request::DATUM_POINT);
            SK.GetEntity(hr.entity(0))->PointForceTo(v);
            ConstrainPointByHovered(hr.entity(0));

            ClearSuper();
            break;

        case MNU_LINE_SEGMENT:
            hr = AddRequest(Request::LINE_SEGMENT);
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            ConstrainPointByHovered(hr.entity(1));

            ClearSuper();

            pending.operation = DRAGGING_NEW_LINE_POINT;
            pending.point = hr.entity(2);
            pending.description = "click next point of line, or press Esc";
            SK.GetEntity(pending.point)->PointForceTo(v);
            break;

        case MNU_RECTANGLE: {
            if(!SS.GW.LockedInWorkplane()) {
                Error("Can't draw rectangle in 3d; select a workplane first.");
                ClearSuper();
                break;
            }
            hRequest lns[4];
            int i;
            SS.UndoRemember();
            for(i = 0; i < 4; i++) {
                lns[i] = AddRequest(Request::LINE_SEGMENT, false);
            }
            for(i = 0; i < 4; i++) {
                Constraint::ConstrainCoincident(
                    lns[i].entity(1), lns[(i+1)%4].entity(2));
                SK.GetEntity(lns[i].entity(1))->PointForceTo(v);
                SK.GetEntity(lns[i].entity(2))->PointForceTo(v);
            }
            for(i = 0; i < 4; i++) {
                Constraint::Constrain(
                    (i % 2) ? Constraint::HORIZONTAL : Constraint::VERTICAL,
                    Entity::NO_ENTITY, Entity::NO_ENTITY,
                    lns[i].entity(0));
            }
            ConstrainPointByHovered(lns[2].entity(1));

            pending.operation = DRAGGING_NEW_POINT;
            pending.point = lns[1].entity(2);
            pending.description = "click to place other corner of rectangle";
            break;
        }
        case MNU_CIRCLE:
            hr = AddRequest(Request::CIRCLE);
            // Centered where we clicked
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            // Normal to the screen
            SK.GetEntity(hr.entity(32))->NormalForceTo(
                Quaternion::From(SS.GW.projRight, SS.GW.projUp));
            // Initial radius zero
            SK.GetEntity(hr.entity(64))->DistanceForceTo(0);

            ConstrainPointByHovered(hr.entity(1));

            ClearSuper();

            pending.operation = DRAGGING_NEW_RADIUS;
            pending.circle = hr.entity(0);
            pending.description = "click to set radius";
            break;

        case MNU_ARC: {
            if(!SS.GW.LockedInWorkplane()) {
                Error("Can't draw arc in 3d; select a workplane first.");
                ClearPending();
                break;
            }
            hr = AddRequest(Request::ARC_OF_CIRCLE);
            // This fudge factor stops us from immediately failing to solve
            // because of the arc's implicit (equal radius) tangent.
            Vector adj = SS.GW.projRight.WithMagnitude(2/SS.GW.scale);
            SK.GetEntity(hr.entity(1))->PointForceTo(v.Minus(adj));
            SK.GetEntity(hr.entity(2))->PointForceTo(v);
            SK.GetEntity(hr.entity(3))->PointForceTo(v);
            ConstrainPointByHovered(hr.entity(2));

            ClearSuper();

            pending.operation = DRAGGING_NEW_ARC_POINT;
            pending.point = hr.entity(3);
            pending.description = "click to place point";
            break;
        }
        case MNU_CUBIC:
            hr = AddRequest(Request::CUBIC);
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            SK.GetEntity(hr.entity(2))->PointForceTo(v);
            SK.GetEntity(hr.entity(3))->PointForceTo(v);
            SK.GetEntity(hr.entity(4))->PointForceTo(v);
            ConstrainPointByHovered(hr.entity(1));

            ClearSuper();

            pending.operation = DRAGGING_NEW_CUBIC_POINT;
            pending.point = hr.entity(4);
            pending.description = "click next point of cubic, or press Esc";
            break;

        case MNU_WORKPLANE:
            if(LockedInWorkplane()) {
                Error("Sketching in a workplane already; sketch in 3d before "
                      "creating new workplane.");
                ClearSuper();
                break;
            }
            hr = AddRequest(Request::WORKPLANE);
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            SK.GetEntity(hr.entity(32))->NormalForceTo(
                Quaternion::From(SS.GW.projRight, SS.GW.projUp));
            ConstrainPointByHovered(hr.entity(1));

            ClearSuper();
            break;

        case MNU_TTF_TEXT: {
            if(!SS.GW.LockedInWorkplane()) {
                Error("Can't draw text in 3d; select a workplane first.");
                ClearSuper();
                break;
            }
            hr = AddRequest(Request::TTF_TEXT);
            Request *r = SK.GetRequest(hr);
            r->str.strcpy("Abc");
            r->font.strcpy("arial.ttf");

            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            SK.GetEntity(hr.entity(2))->PointForceTo(v);

            pending.operation = DRAGGING_NEW_POINT;
            pending.point = hr.entity(2);
            pending.description = "click to place bottom left of text";
            break;
        }

        case MNU_COMMENT: {
            ClearSuper();
            Constraint c;
            ZERO(&c);
            c.group       = SS.GW.activeGroup;
            c.workplane   = SS.GW.ActiveWorkplane();
            c.type        = Constraint::COMMENT;
            c.disp.offset = v;
            c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
            Constraint::AddConstraint(&c);
            break;
        }

        case DRAGGING_RADIUS:
        case DRAGGING_NEW_POINT:
            // The MouseMoved event has already dragged it as desired.
            ClearPending();
            break;

        case DRAGGING_NEW_ARC_POINT:
            ConstrainPointByHovered(pending.point);
            ClearPending();
            break;

        case DRAGGING_NEW_CUBIC_POINT: {
            hRequest hr = pending.point.request();
            Request *r = SK.GetRequest(hr);

            if(hover.entity.v == hr.entity(1).v && r->extraPoints >= 2) {
                // They want the endpoints coincident, which means a periodic
                // spline instead.
                r->type = Request::CUBIC_PERIODIC;
                // Remove the off-curve control points, which are no longer
                // needed here; so move [2,ep+1] down, skipping first pt.
                int i;
                for(i = 2; i <= r->extraPoints+1; i++) {
                    SK.GetEntity(hr.entity((i-1)+1))->PointForceTo(
                        SK.GetEntity(hr.entity(i+1))->PointGetNum());
                }
                // and move ep+3 down by two, skipping both
                SK.GetEntity(hr.entity((r->extraPoints+1)+1))->PointForceTo(
                  SK.GetEntity(hr.entity((r->extraPoints+3)+1))->PointGetNum());
                r->extraPoints -= 2;
                // And we're done.
                SS.MarkGroupDirty(r->group);
                SS.ScheduleGenerateAll();
                ClearPending();
                break;
            }

            if(ConstrainPointByHovered(pending.point)) {
                ClearPending();
                break;
            }

            Entity e;
            if(r->extraPoints >= (int)arraylen(e.point) - 4) {
                ClearPending();
                break;
            }

            (SK.GetRequest(hr)->extraPoints)++;
            SS.GenerateAll(-1, -1);

            int ep = r->extraPoints;
            Vector last = SK.GetEntity(hr.entity(3+ep))->PointGetNum();

            SK.GetEntity(hr.entity(2+ep))->PointForceTo(last);
            SK.GetEntity(hr.entity(3+ep))->PointForceTo(v);
            SK.GetEntity(hr.entity(4+ep))->PointForceTo(v);
            pending.point = hr.entity(4+ep);
            break;
        }

        case DRAGGING_NEW_LINE_POINT: {
            if(hover.entity.v) {
                Entity *e = SK.GetEntity(hover.entity);
                if(e->IsPoint()) {
                    hRequest hrl = pending.point.request();
                    Entity *sp = SK.GetEntity(hrl.entity(1));
                    if(( e->PointGetNum()).Equals(
                       (sp->PointGetNum())))
                    {
                        // If we constrained by the hovered point, then we
                        // would create a zero-length line segment. That's
                        // not good, so just stop drawing.
                        ClearPending();
                        break;
                    }
                }
            }

            if(ConstrainPointByHovered(pending.point)) {
                ClearPending();
                break;
            }

            // Create a new line segment, so that we continue drawing.
            hRequest hr = AddRequest(Request::LINE_SEGMENT);
            SK.GetEntity(hr.entity(1))->PointForceTo(v);
            // Displace the second point of the new line segment slightly,
            // to avoid creating zero-length edge warnings.
            SK.GetEntity(hr.entity(2))->PointForceTo(
                v.Plus(projRight.ScaledBy(0.5/scale)));

            // Constrain the line segments to share an endpoint
            Constraint::ConstrainCoincident(pending.point, hr.entity(1));

            // And drag an endpoint of the new line segment
            pending.operation = DRAGGING_NEW_LINE_POINT;
            pending.point = hr.entity(2);
            pending.description = "click next point of line, or press Esc";

            break;
        }

        case 0:
        default:
            ClearPending();
            if(!hover.IsEmpty()) {
                hoverWasSelectedOnMousedown = IsSelected(&hover);
                MakeSelected(&hover);
            }
            break;
    }

    SS.ScheduleShowTW();
    InvalidateGraphics();
}
Ejemplo n.º 25
0
 void BitRequestList::AddRequest(Iterator first, Iterator last)
 {
     for (; first != last; ++first)
         AddRequest(first->index, first->begin, first->length);
 }
Ejemplo n.º 26
0
int
CCBServer::HandleRequest(int cmd,Stream *stream)
{
	ReliSock *sock = (ReliSock *)stream;
	ASSERT( cmd == CCB_REQUEST );

		// Avoid lengthy blocking on communication with our peer.
		// This command-handler should not get called until data
		// is ready to read.
	sock->timeout(1);

	ClassAd msg;
	sock->decode();
	if( !msg.initFromStream( *sock ) || !sock->end_of_message() ) {
		dprintf(D_ALWAYS,
				"CCB: failed to receive request "
				"from %s.\n", sock->peer_description() );
		return FALSE;
	}

	MyString name;
	if( msg.LookupString(ATTR_NAME,name) ) {
			// client name is purely for debugging purposes
		name.formatstr_cat(" on %s",sock->peer_description());
		sock->set_peer_description(name.Value());
	}
	MyString target_ccbid_str;
	MyString return_addr;
	MyString connect_id; // id target daemon should present to requester
	CCBID target_ccbid;

		// NOTE: using ATTR_CLAIM_ID for connect id so that it is
		// automatically treated as a secret over the network.
		// It must be presented by the target daemon when connecting
		// to the requesting client, so the client can confirm that
		// the connection is in response to its request.

	if( !msg.LookupString(ATTR_CCBID,target_ccbid_str) ||
		!msg.LookupString(ATTR_MY_ADDRESS,return_addr) ||
		!msg.LookupString(ATTR_CLAIM_ID,connect_id) )
	{
		MyString ad_str;
		msg.sPrint(ad_str);
		dprintf(D_ALWAYS,
				"CCB: invalid request from %s: %s\n",
				sock->peer_description(), ad_str.Value() );
		return FALSE;
	}
	if( !CCBIDFromString(target_ccbid,target_ccbid_str.Value()) ) {
		dprintf(D_ALWAYS,
				"CCB: request from %s contains invalid CCBID %s\n",
				sock->peer_description(), target_ccbid_str.Value() );
		return FALSE;
	}

	CCBTarget *target = GetTarget( target_ccbid );
	if( !target ) {
		dprintf(D_ALWAYS,
			"CCB: rejecting request from %s for ccbid %s because no daemon is "
			"currently registered with that id "
			"(perhaps it recently disconnected).\n",
			sock->peer_description(), target_ccbid_str.Value());

		MyString error_msg;
		error_msg.formatstr(
			"CCB server rejecting request for ccbid %s because no daemon is "
			"currently registered with that id "
			"(perhaps it recently disconnected).", target_ccbid_str.Value());
		RequestReply( sock, false, error_msg.Value(), 0, target_ccbid );
		return FALSE;
	}

	SetSmallBuffers(sock);

	CCBServerRequest *request =
		new CCBServerRequest(
			sock,
			target_ccbid,
			return_addr.Value(),
			connect_id.Value() );
	AddRequest( request, target );

	dprintf(D_FULLDEBUG,
			"CCB: received request id %lu from %s for target ccbid %s "
			"(registered as %s)\n",
			request->getRequestID(),
			request->getSock()->peer_description(),
			target_ccbid_str.Value(),
			target->getSock()->peer_description());

	ForwardRequestToTarget( request, target );

	return KEEP_STREAM;
}
Ejemplo n.º 27
0
void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) {
    Entity *wrkpl  = SK.GetEntity(ActiveWorkplane());
    Entity *wrkpln = SK.GetEntity(wrkpl->normal);
    Vector u = wrkpln->NormalU(),
           v = wrkpln->NormalV(),
           n = wrkpln->NormalN(),
           p = SK.GetEntity(wrkpl->point[0])->PointGetNum();

    ClipboardRequest *cr;
    for(cr = SS.clipboard.r.First(); cr; cr = SS.clipboard.r.NextAfter(cr)) {
        hRequest hr = AddRequest(cr->type, false);
        Request *r = SK.GetRequest(hr);
        r->extraPoints  = cr->extraPoints;
        r->style        = cr->style;
        r->str.strcpy(    cr->str.str);
        r->font.strcpy(   cr->font.str);
        r->construction = cr->construction;
        // Need to regen to get the right number of points, if extraPoints
        // changed.
        SS.GenerateAll(-1, -1);
        SS.MarkGroupDirty(r->group);
        bool hasDistance;
        int i, pts;
        EntReqTable::GetRequestInfo(r->type, r->extraPoints,
            NULL, &pts, NULL, &hasDistance);
        for(i = 0; i < pts; i++) {
            Vector pt = cr->point[i];
            // We need the reflection to occur within the workplane; it may
            // otherwise correspond to just a rotation as projected.
            if(scale < 0) {
                pt.x *= -1;
            }
            // Likewise the scale, which could otherwise take us out of the
            // workplane.
            pt = pt.ScaledBy(fabs(scale));
            pt = pt.ScaleOutOfCsys(u, v, Vector::From(0, 0, 0));
            pt = pt.Plus(p);
            pt = pt.RotatedAbout(n, theta);
            pt = pt.Plus(trans);
            SK.GetEntity(hr.entity(i+1))->PointForceTo(pt);
        }
        if(hasDistance) {
            SK.GetEntity(hr.entity(64))->DistanceForceTo(
                                            cr->distance*fabs(scale));
        }

        cr->newReq = hr;
        MakeSelected(hr.entity(0));
        for(i = 0; i < pts; i++) {
            MakeSelected(hr.entity(i+1));
        }
    }
    
    Constraint *c;
    for(c = SS.clipboard.c.First(); c; c = SS.clipboard.c.NextAfter(c)) {
        if(c->type == Constraint::POINTS_COINCIDENT) {
            Constraint::ConstrainCoincident(SS.clipboard.NewEntityFor(c->ptA),
                                            SS.clipboard.NewEntityFor(c->ptB));
        }
    }

    SS.later.generateAll = true;
}
Ejemplo n.º 28
0
hRequest GraphicsWindow::AddRequest(int type) {
    return AddRequest(type, true);
}
Ejemplo n.º 29
0
//-----------------------------------------------------------------------------
// A single point must be selected when this function is called. We find two
// non-construction line segments that join at this point, and create a
// tangent arc joining them.
//-----------------------------------------------------------------------------
void GraphicsWindow::MakeTangentArc(void) {
    if(!LockedInWorkplane()) {
        Error("Must be sketching in workplane to create tangent "
              "arc.");
        return;
    }

    // The point corresponding to the vertex to be rounded.
    Vector pshared = SK.GetEntity(gs.point[0])->PointGetNum();
    ClearSelection();

    // First, find two requests (that are not construction, and that are
    // in our group and workplane) that generate entities that have an
    // endpoint at our vertex to be rounded.
    int i, c = 0;
    Entity *ent[2];
    Request *req[2];
    hRequest hreq[2];
    hEntity hent[2];
    bool pointf[2];
    for(i = 0; i < SK.request.n; i++) {
        Request *r = &(SK.request.elem[i]);
        if(r->group.v != activeGroup.v) continue;
        if(r->workplane.v != ActiveWorkplane().v) continue;
        if(r->construction) continue;
        if(r->type != Request::LINE_SEGMENT &&
           r->type != Request::ARC_OF_CIRCLE)
        {
            continue;
        }

        Entity *e = SK.GetEntity(r->h.entity(0));
        Vector ps = e->EndpointStart(),
               pf = e->EndpointFinish();
        
        if(ps.Equals(pshared) || pf.Equals(pshared)) {
            if(c < 2) {
                // We record the entity and request and their handles,
                // and whether the vertex to be rounded is the start or
                // finish of this entity.
                ent[c] = e;
                hent[c] = e->h;
                req[c] = r;
                hreq[c] = r->h;
                pointf[c] = (pf.Equals(pshared));
            }
            c++;
        }
    }
    if(c != 2) {
        Error("To create a tangent arc, select a point where two "
              "non-construction lines or cicles in this group and "
              "workplane join.");
        return;
    }

    Entity *wrkpl = SK.GetEntity(ActiveWorkplane());
    Vector wn = wrkpl->Normal()->NormalN();

    // Based on these two entities, we make the objects that we'll use to
    // numerically find the tangent arc.
    ParametricCurve pc[2];
    pc[0].MakeFromEntity(ent[0]->h, pointf[0]);
    pc[1].MakeFromEntity(ent[1]->h, pointf[1]);

    // And thereafter we mustn't touch the entity or req ptrs,
    // because the new requests/entities we add might force a
    // realloc.
    memset(ent, 0, sizeof(ent));
    memset(req, 0, sizeof(req));

    Vector pinter;
    double r, vv;
    // We now do Newton iterations to find the tangent arc, and its positions
    // t back along the two curves, starting from shared point of the curves
    // at t = 0. Lots of iterations helps convergence, and this is still
    // ~10 ms for everything.
    int iters = 1000;
    double t[2] = { 0, 0 }, tp[2];
    for(i = 0; i < iters + 20; i++) {
        Vector p0 = pc[0].PointAt(t[0]),
               p1 = pc[1].PointAt(t[1]),
               t0 = pc[0].TangentAt(t[0]),
               t1 = pc[1].TangentAt(t[1]);

        pinter = Vector::AtIntersectionOfLines(p0, p0.Plus(t0),
                                               p1, p1.Plus(t1),
                                               NULL, NULL, NULL);

        // The sign of vv determines whether shortest distance is
        // clockwise or anti-clockwise.
        Vector v = (wn.Cross(t0)).WithMagnitude(1);
        vv = t1.Dot(v);

        double dot = (t0.WithMagnitude(1)).Dot(t1.WithMagnitude(1));
        double theta = acos(dot);

        if(SS.tangentArcManual) {
            r = SS.tangentArcRadius;
        } else {
            r = 200/scale;
            // Set the radius so that no more than one third of the 
            // line segment disappears.
            r = min(r, pc[0].LengthForAuto()*tan(theta/2));
            r = min(r, pc[1].LengthForAuto()*tan(theta/2));;
        }
        // We are source-stepping the radius, to improve convergence. So
        // ramp that for most of the iterations, and then do a few at
        // the end with that constant for polishing.
        if(i < iters) {
            r *= 0.1 + 0.9*i/((double)iters);
        }

        // The distance from the intersection of the lines to the endpoint
        // of the arc, along each line.
        double el = r/tan(theta/2);

        // Compute the endpoints of the arc, for each curve
        Vector pa0 = pinter.Plus(t0.WithMagnitude(el)),
               pa1 = pinter.Plus(t1.WithMagnitude(el));

        tp[0] = t[0];
        tp[1] = t[1];

        // And convert those points to parameter values along the curve.
        t[0] += (pa0.Minus(p0)).DivPivoting(t0);
        t[1] += (pa1.Minus(p1)).DivPivoting(t1);
    }

    // Stupid check for convergence, and for an out of range result (as
    // we would get, for example, if the line is too short to fit the
    // rounding arc).
    if(fabs(tp[0] - t[0]) > 1e-3 || fabs(tp[1] - t[1]) > 1e-3 ||
        t[0] < 0.01 || t[1] < 0.01 ||
        t[0] > 0.99 || t[1] > 0.99 ||
        isnan(t[0]) || isnan(t[1]))
    {
        Error("Couldn't round this corner. Try a smaller radius, or try "
              "creating the desired geometry by hand with tangency "
              "constraints.");
        return;
    }

    // Compute the location of the center of the arc
    Vector center = pc[0].PointAt(t[0]),
           v0inter = pinter.Minus(center);
    int a, b;
    if(vv < 0) {
        a = 1; b = 2;
        center = center.Minus(v0inter.Cross(wn).WithMagnitude(r));
    } else {
        a = 2; b = 1;
        center = center.Plus(v0inter.Cross(wn).WithMagnitude(r));
    }

    SS.UndoRemember();

    hRequest harc = AddRequest(Request::ARC_OF_CIRCLE, false);
    Entity *earc = SK.GetEntity(harc.entity(0));
    hEntity hearc = earc->h;

    SK.GetEntity(earc->point[0])->PointForceTo(center);
    SK.GetEntity(earc->point[a])->PointForceTo(pc[0].PointAt(t[0]));
    SK.GetEntity(earc->point[b])->PointForceTo(pc[1].PointAt(t[1]));
    
    earc = NULL;

    pc[0].CreateRequestTrimmedTo(t[0], !SS.tangentArcDeleteOld,
                hent[0], hearc, (b == 1));
    pc[1].CreateRequestTrimmedTo(t[1], !SS.tangentArcDeleteOld,
                hent[1], hearc, (a == 1));

    // Now either make the original entities construction, or delete them
    // entirely, according to user preference.
    Request *re;
    SK.request.ClearTags();
    for(re = SK.request.First(); re; re = SK.request.NextAfter(re)) {
        if(re->h.v == hreq[0].v || re->h.v == hreq[1].v) {
            if(SS.tangentArcDeleteOld) {
                re->tag = 1;
            } else {
                re->construction = true;
            }
        }
    }
    if(SS.tangentArcDeleteOld) {
        DeleteTaggedRequests();
    }

    SS.later.generateAll = true;
}
Ejemplo n.º 30
0
hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
    // Save the original endpoints, since we're about to delete this entity.
    Entity *e01 = SK.GetEntity(he);
    SBezierList sbl;
    ZERO(&sbl);
    e01->GenerateBezierCurves(&sbl);

    hEntity hep0 = e01->point[0],
            hep1 = e01->point[3+e01->extraPoints],
            hep0n = Entity::NO_ENTITY, // the new start point
            hep1n = Entity::NO_ENTITY, // the new finish point
            hepin = Entity::NO_ENTITY; // the intersection point

    // The curve may consist of multiple cubic segments. So find which one
    // contains the intersection point.
    double t;
    int i, j;
    for(i = 0; i < sbl.l.n; i++) {
        SBezier *sb = &(sbl.l.elem[i]);
        if(sb->deg != 3) oops();

        sb->ClosestPointTo(pinter, &t, false);
        if(pinter.Equals(sb->PointAt(t))) {
            // Split that segment at the intersection.
            SBezier b0i, bi1, b01 = *sb;
            b01.SplitAt(t, &b0i, &bi1);

            // Add the two cubic segments this one gets split into.
            hRequest r0i = AddRequest(Request::CUBIC, false),
                     ri1 = AddRequest(Request::CUBIC, false);
            // Don't get entities till after adding, realloc issues

            Entity *e0i = SK.GetEntity(r0i.entity(0)),
                   *ei1 = SK.GetEntity(ri1.entity(0));

            for(j = 0; j <= 3; j++) {
                SK.GetEntity(e0i->point[j])->PointForceTo(b0i.ctrl[j]);
            }
            for(j = 0; j <= 3; j++) {
                SK.GetEntity(ei1->point[j])->PointForceTo(bi1.ctrl[j]);
            }

            Constraint::ConstrainCoincident(e0i->point[3], ei1->point[0]);
            if(i == 0) hep0n = e0i->point[0];
            hep1n = ei1->point[3];
            hepin = e0i->point[3];
        } else {
            hRequest r = AddRequest(Request::CUBIC, false);
            Entity *e = SK.GetEntity(r.entity(0));

            for(j = 0; j <= 3; j++) {
                SK.GetEntity(e->point[j])->PointForceTo(sb->ctrl[j]);
            }

            if(i == 0) hep0n = e->point[0];
            hep1n = e->point[3];
        }
    }

    sbl.Clear();

    ReplacePointInConstraints(hep0, hep0n);
    ReplacePointInConstraints(hep1, hep1n);
    return hepin;
}