/**
 * @brief Run the analysis.
 */
void CNFamilialAnalysisMethodGenotypeConcordance::run()
{
    Verbose::out(1, "CNFamilialAnalysisMethodGenotypeConcordance::run(...) start");
    CNCychp& cychpIndex = getCychpIndex();
    CNCychp& cychpMother = getCychpMother();
    CNCychp& cychpFather = getCychpFather();

    getIndexSegments().deleteAll();
    getMotherSegments().deleteAll();
    getFatherSegments().deleteAll();

    int iProbeSetCount = cychpIndex.getCychpProbeSetsCopyNumbers().getCount();
    if (cychpMother.getFamilialCall() == 1)
    {
        Verbose::progressBegin(1, "CNFamilialAnalysisMethodGenotypeConcordance::run(...) Mother's segments ", iProbeSetCount, 100000, (iProbeSetCount / 100000));
        for (int i = 0; (i < iProbeSetCount); i++)
        {
            Verbose::progressStep(1);
            CNCychpProbeSetsCopyNumber* pIndex = cychpIndex.getCychpProbeSetsCopyNumbers().getAt(i);
            CNCychpProbeSetsCopyNumber* pMother = cychpMother.getCychpProbeSetsCopyNumbers().getAt(i);
            if ((pMother->getGenotypeCall() == -1) || (pIndex->getGenotypeCall() == -1))
            {
                pMother->setSegmentInput(-1);
            }
            else
            {
                pMother->setSegmentInput(1);
                if (isGenotypeConcordance(pIndex, pMother)) {pMother->setSegmentInput(0);}
            }
        }
        anneal(cychpMother);
        newSegments(cychpIndex, cychpMother, 1, getMotherSegments(), getSegmentType(), 1, m_iMarkerCountCutoff, m_iCallCutoff, m_iMinGenomicSpan);
        Verbose::progressEnd(1, "Done");
    }
    if (cychpFather.getFamilialCall() == 1)
    {
        Verbose::progressBegin(1, "CNFamilialAnalysisMethodGenotypeConcordance::run(...) Father's segments ", iProbeSetCount, 100000, (iProbeSetCount / 100000));
        for (int i = 0; (i < iProbeSetCount); i++)
        {
            Verbose::progressStep(1);
            CNCychpProbeSetsCopyNumber* pIndex = cychpIndex.getCychpProbeSetsCopyNumbers().getAt(i);
            CNCychpProbeSetsCopyNumber* pFather = cychpFather.getCychpProbeSetsCopyNumbers().getAt(i);
            if ((pFather->getGenotypeCall() == -1) || (pIndex->getGenotypeCall() == -1))
            {
                pFather->setSegmentInput(-1);
            }
            else
            {
                pFather->setSegmentInput(1);
                if (isGenotypeConcordance(pIndex, pFather)) {pFather->setSegmentInput(0);}
            }
        }
        anneal(cychpFather);
        newSegments(cychpIndex, cychpFather, 2, getFatherSegments(), getSegmentType(), 1, m_iMarkerCountCutoff, m_iCallCutoff, m_iMinGenomicSpan);
        Verbose::progressEnd(1, "Done");
    }
    Verbose::out(1, "CNFamilialAnalysisMethodGenotypeConcordance::run(...) end");
}
/**
 * @brief Run the analysis.
 */
void CNAnalysisMethodNormalDiploid::run()
{
    Verbose::out(1, "CNAnalysisMethodNormalDiploid::run(...) start");
	isSetup();
    determineLocalProbeSets();
    m_vSegments.deleteAll();
    newSegments(getSegmentType(), getProbeSets());
    Verbose::out(1, "CNAnalysisMethodNormalDiploid::run(...) end");
}
Example #3
0
CFASegmentPtr newSegment(FILE* fin, int* last) {
	static const int stubSize = sizeof(CFASegmentStub);
	CFASegmentPtr segm;
	CFASegmentStub* stub = malloc(stubSize);
	fread(stub, 1, sizeof(CFASegmentStub), fin);

	if (stub->shebang != CFA_SHEBANG) {
		free(stub);
		return NULL;
	}

	stub = realloc(stub, stub->headerSizeBytes + stub->fwSizeBytes);
	fread((char*)stub + stubSize, 1, stub->headerSizeBytes + stub->fwSizeBytes - stubSize, fin);
	if (getSegmentType(stub) == CFA_SEGMENT_TYPE_1) {
		int i, jump = 0;
		CFASegmentType1* t1s = malloc(sizeof(CFASegmentType1));
		memcpy(t1s, stub, sizeof(CFASegmentType1));

		t1s->models = calloc(t1s->numModels, sizeof(CFAModelType1*));
		for (i=0; i < t1s->numModels; i++) {
			CFAModelType1* first = (CFAModelType1*)((char*)stub+stubSize+CFA_SEGMENT_T1_FAMILY_FIELDS_SIZE);
			int size = ((CFAModelType1*)((char*)first + jump))->numChecks * 8 + 8;
			t1s->models[i] = malloc(size);
			memcpy(t1s->models[i], (char*)first + jump, size);
			jump += size;
		}
		t1s->fwData = malloc(t1s->fwSizeBytes);
		memcpy(t1s->fwData, (char*)stub+stub->headerSizeBytes, t1s->fwSizeBytes);
		segm = t1s;
	} else {
		int i, jump = 0;
		CFASegmentType2* t2s = malloc(sizeof(CFASegmentType2));
		memcpy(t2s, stub, sizeof(CFASegmentType2));

		t2s->models = calloc(t2s->numModels, sizeof(CFAModelType2*));
		for (i=0; i < t2s->numModels; i++) {
			CFAModelType2* first = (CFAModelType2*)((char*)stub+stubSize);
			int size = 4;
			t2s->models[i] = malloc(size);
			memcpy(t2s->models[i], (char*)first + jump, size);
			jump += size;
		}
		t2s->fwData = malloc(t2s->fwSizeBytes);
		memcpy(t2s->fwData, (char*)stub+stub->headerSizeBytes, t2s->fwSizeBytes);
		segm = t2s;
	}

	if (last != NULL) *last = stub->lastHeader;

	free(stub);

	return segm;
}
Example #4
0
void deleteSegment(CFASegmentPtr segm) {
	int i;
	if (getSegmentType(segm) == CFA_SEGMENT_TYPE_1) {
		CFASegmentType1* t1s = toType1(segm);
		for (i=0; i<t1s->numModels; i++)
			free(t1s->models[i]);
		free(t1s->models);
	} else {
		CFASegmentType2* t2s = toType2(segm);
		for (i=0; i<t2s->numModels; i++)
			free(t2s->models[i]);
		free(t2s->models);
	}
	free(segm);
}
/**
 * @brief Run the analysis.
 * Denovo is when the Index CN != the CN of either parent.
 */
void CNFamilialAnalysisMethodDenovoCopyNumber::run()
{
    Verbose::out(1, "CNFamilialAnalysisMethodDenovoCopyNumber::run(...) start");
    CNCychp& cychpIndex = getCychpIndex();
    CNCychp& cychpMother = getCychpMother();
    CNCychp& cychpFather = getCychpFather();

    getIndexSegments().deleteAll();
    getMotherSegments().deleteAll();
    getFatherSegments().deleteAll();

    if ((cychpMother.getFamilialCall() == 0) && (cychpFather.getFamilialCall() == 0)) {return;}

    int iProbeSetCount = cychpIndex.getCychpProbeSetsCopyNumbers().getCount();
    if ((cychpMother.getFamilialCall() == 1) && (cychpFather.getFamilialCall() == 1))
    {
        Verbose::progressBegin(1, "CNFamilialAnalysisMethodDenovoCopyNumber::run(...) Index's segments ", iProbeSetCount, 100000, (iProbeSetCount / 100000));
        for (int i = 0; (i < iProbeSetCount); i++)
        {
            Verbose::progressStep(1);
            CNCychpProbeSetsCopyNumber* pIndex = cychpIndex.getCychpProbeSetsCopyNumbers().getAt(i);
            CNCychpProbeSetsCopyNumber* pMother = cychpMother.getCychpProbeSetsCopyNumbers().getAt(i);
            CNCychpProbeSetsCopyNumber* pFather = cychpFather.getCychpProbeSetsCopyNumbers().getAt(i);
            pIndex->setSegmentInput(1);
            if ((pIndex->getCnCall() != pMother->getCnCall()) && (pIndex->getCnCall() != pFather->getCnCall()))
            {
                pIndex->setSegmentInput(0);
            }
        }
        anneal(cychpIndex);
        newSegments(cychpIndex, cychpIndex, 0, getIndexSegments(), getSegmentType(), 1, m_iMarkerCountCutoff, m_iCallCutoff, m_iMinGenomicSpan);

        Verbose::progressEnd(1, "Done");
    }
    Verbose::out(1, "CNFamilialAnalysisMethodDenovoCopyNumber::run(...) end");
}
Example #6
0
int main (){

  int sock_main, sock_timer;
  struct sockaddr_in main, timer;
  char buf[TCP_SEGMENT_SIZE];
  char hostname[128];
  gethostname (hostname, sizeof(hostname));
  hp = gethostbyname(hostname); 
  
  sock_main = socket (AF_INET, SOCK_DGRAM, 0);
  
  if (sock_main < 0){
    perror("opening UDP socket for main use");
    exit(1);
  }

  bzero ((char*)&main, sizeof (main));
  main.sin_family = AF_INET;
  main.sin_port = TCPD_PORT;
  bcopy((void *)hp->h_addr_list[0], (void *)&main.sin_addr, hp->h_length);
    
  if (bind(sock_main, (struct sockaddr *)&main, sizeof(main)) < 0){
    perror("getting socket name of main TCPD port");
    exit(2);
  }

  printf("TCPD MAIN SOCKET : PORT = %d ADDR = %d\n",main.sin_port,main.sin_addr.s_addr);  
 
  bzero((char*)&timer, sizeof(timer));
  timer.sin_family = AF_INET;
  timer.sin_port = TIMER_PORT;
  bcopy((void *)hp->h_addr_list[0], (void *)&timer.sin_addr, hp->h_length);
  
  /* TODO : Initialize send and receive windows */
  sendWindow.low = 100;
  sendWindow.high = sendWindow.low + WINDOW_SIZE * TCP_MSS;
  recvWindow.low = 100;
  recvWindow.high = recvWindow.low + WINDOW_SIZE * TCP_MSS;

  while (1){
    
      int type = 0;
      void *ptr = NULL;
      int send_bytes = 0;
      int sock  = 0;
      int rlen = 0;
      int i = 0;
      TCP_segment ts;
      TCP_segment ts_recv;
      TCP_segment* tsp;
      struct sockaddr_in name;
      
      /*
      printf("Inside child process to receive data\n");
      */
      printf("\n\n");
      
      /* Initialize buffer to all zeroes */
      bzero(buf, TCP_MSS);
       
      /* Receive data from UDP port */
      rlen = recvSegment((TCP_segment *)&ts, sock_main, main);
       
      /* Get segment type (LOCAL, REMOTE or TIMER) */
      type = getSegmentType (ts);      

      /*
      printf("Segment Type = %d len = %d\n",type,rlen);
      */
    
      /* Segment received from local application process */
      if (type == LOCAL_SEGMENT) {
        
        printf("Received local segment len = %d\n",rlen);
        printf("sBufCount = %d\n",sBufCount);

        printf("Send window : (%d, %d)\n",sendWindow.low, sendWindow.high);        
        
        /* Receiving destination address when a CONNECT is called*/
        if (ts.hdr.seq == DEST_INFO) {
          memcpy ((void*)&dest, (void*)&(ts.data), sizeof(struct sockaddr_in));
          printf("Received destination info from app\n");
          continue;
        }
        /* Receiving source address when a BIND is called*/
        else if (ts.hdr.seq == SRC_INFO) {
          memcpy ((void*)&src, (void*)&(ts.data), sizeof(struct sockaddr_in));
          printf("Received source info from app port = %d\n",src.sin_port);
          continue;
        }

        /* 
        memcpy((void*)&buf[0], (void*)&ts.data, rlen-TCP_HEADER_SIZE);
        for (i = 0; i < rlen-TCP_HEADER_SIZE; ++i)
          printf("%d", buf[i]);
        printf("Recv bytes = %d\n",rlen-TCP_HEADER_SIZE);
        */
        if (sBufCount == BUFFER_SIZE) continue;
        /*
        sBufCount++;
        */
        /* Construct TCP segment with received data */
        ts = constructSegment((void*)&ts.data, rlen-TCP_HEADER_SIZE);
             
        /* Sequence number gets incremented by 
         * 1 for each byte sent */
        nextSeq = nextSeq + rlen-TCP_HEADER_SIZE;

        /* Add segment to send buffer */
        /* TODO: Revisit buffer overflow logic here */
        
        memcpy((void*)&buf, (void*) &ts.data, rlen);
        /*
        for (i = 0; i < rlen; ++i)
          printf("%c");
        printf("\n");
        */
        sBufPtr = addToBuffer (sBufPtr, &sBufCount, ts, rlen); 
          
        /* Send from send buffer */
        sendFromSendBuffer (sBufPtr, sock_main, dest, timer, SEND_ALL, NULL); 
            
      }
      /* Segment received from remote process */
      
      else if (type == REMOTE_SEGMENT) {
        printf("Received remote segment len = %d\n",rlen);
        
        printf("Recv window : (%d, %d)\n",recvWindow.low, recvWindow.high);        
        
        /* TODO : Checksum here */ 
        /*
        printf("seq = %d crc = %d len = %d\n",ts.hdr.seq,ts.hdr.sum, rlen);
        
        memcpy((void*)&buf[0], (void*)&ts, rlen);
        for (i = 0; i < TCP_HEADER_SIZE; ++i)
          printf("%d",buf[i]);
        printf("\n");
        */

        /* Check if segment has valid checksum */
        if (!isValidChecksum(&ts, rlen)){
          printf("Checksum FAILURE\n");
          continue;
        }
        printf("Checksum SUCCESS\n");

 
        /* Check if ACK flag is set */
        if (isACK(&ts)){
          /* TODO :Handle ACK for already ACKed segments here */
          
            printf("Received ACK no = %d\n", ts.hdr.ack);
          
            /* Remove ACKed segment from buffer */
            sBufPtr = removeFromSendBuffer(sBufPtr, sock_main, timer, ts.hdr.ack);        
          
            /* Maintain ACK Count and compute RTO  */
            ackCount += 1;

            computeRTO ();

            continue;
        }
         
        /* Check if segment has valid checksum */
        /*
        if (!isValidChecksum(&ts, rlen)){
          printf("Checksum FAILURE");
          continue;
        }
        printf("Checksum SUCCESS\n");
        */
       
        /* Process received segment and return ptr to data*/
        ptr = processSegment((TCP_segment *)&ts, rlen);

        setACKFlag(&ts);

        /* TODO : How ACK set?*/
        ts.hdr.ack = ts.hdr.seq + rlen-TCP_HEADER_SIZE;
        if (isWithinWindow(recvWindow, ts.hdr.seq+rlen-TCP_HEADER_SIZE)|| (ts.hdr.seq < recvWindow.low)){
          
          int seq = ts.hdr.seq;            
          printf("Sending ACK for seq = %d\n",ts.hdr.seq);
          ts.hdr.seq = nextSeq;
          ts.hdr.urp = 0;
          ts.hdr.sum = 0;
          memcpy((void*)&buf, (void*)&ts, TCP_HEADER_SIZE);
  
          ts.hdr.sum = computeChecksum(&buf[0], TCP_HEADER_SIZE, &(ts.hdr.sum));
        
          /*
          printf("Checksum for ACK seq : %d crc : %d len : %d\n",ts.hdr.seq, ts.hdr.sum, TCP_HEADER_SIZE);
          
          for (i = 0; i < TCP_HEADER_SIZE; ++i)
            printf("%d",buf[i]);
          printf("\n");
          */
          /*ts.hdr.urp = REMOTE_SEGMENT;*/
          /*
          for (i = 0; i < TCP_HEADER_SIZE; ++i)
            printf("%d",buf[i]);
          printf("\n");
          */
          /* Sending ACK to remote process */
          sendSegment(&ts, TCP_HEADER_SIZE, sock_main, replyaddr);
          
          nextSeq = nextSeq + TCP_HEADER_SIZE;      
          ts.hdr.seq = seq;
        }
         /*printf("Sent ACK for seq = %d to dest = %d\n",ts.hdr.seq, replyaddr.sin_addr.s_addr);
          */
        if (!isWithinWindow(recvWindow, ts.hdr.seq+rlen-TCP_HEADER_SIZE) 
            || nextExpectedSeq > ts.hdr.seq){
            
          printf("Not within recv window seq = %d\n",ts.hdr.seq);
          continue;
        }
          
        printf("rBufCount = %d\n",rBufCount);          
        /*
        if (rBufPtr != NULL)  printf("RB : headseq = %d nes = %d\n",rBufPtr->ts.hdr.seq, nextExpectedSeq);
        if (rBufPtr != NULL && rBufPtr->ts.hdr.seq < nextExpectedSeq){
          printf("EXITING.......... \n");
          exit(1);
        }
        */
        /*
        if (nextExpectedSeq < recvWindow.low){
          printf("EXITING..\n");
          exit(1);
        }
        */
        
        if (rBufCount == BUFFER_SIZE) continue;
        
        /*rBufCount++;
        */
        /* TODO: Temporary hack to avoid recv buffer */
        /*sendData(&ts, rlen, sock_main, src);  
        
        continue;
        */

        /* Add segment to receive buffer */
        rBufPtr = addToBuffer (rBufPtr, &rBufCount, ts, rlen); 
          
        if (rBufPtr == NULL){
          printf("rbufptr = NULL post adding\n");
          continue; 
        }
        /* Update receive window */          
        updateWindow(&recvWindow, ts.hdr.seq, rlen-TCP_HEADER_SIZE); 
          
        /* Send data to local process */
        rBufPtr = sendFromRecvBuffer(rBufPtr, sock_main, src);
      }
      else if (type == TIMER_SEGMENT){

          TCP_buffer* ptr = NULL;

          printf("Received timer segment len = %d\n",rlen);
       
          memcpy((void*)&ptr, (void*)&(ts.data), sizeof(ptr));
          
          /* Update RTO on timeout. Message from timer 
           * implies timeout. */
          computeRTO();
          
          /* Retransmit segment to remote process */    
          sendFromSendBuffer (sBufPtr, sock_main, dest, timer, SEND_ONE, ptr);   
      }
  }  
  return 0;
}
// This function produces an initial segmentation.
void CNAnalysisMethodMosaicism::newSegments(unsigned char cChromosome, 
                                            double* pRunMean, 
                                            int iProbeSetCount, 
                                            std::vector<int>& vPositions, 
                                            CNSegmentArray& vSegments)
{
    double dNeutralZoneLow = m_vLossesBoundries[0];
    double dNeutralZoneHigh = m_vGainsBoundries[0];
    int iStartIndex = 0;
    int iEndIndex = 0;
    int iIndex = 0;
    double dCurrentMax = 0;

//    int last_vSegments_size=vSegments.size();
    while (iIndex < (iProbeSetCount - 1))
    {
        iStartIndex = iIndex;

        if (((dNeutralZoneLow < pRunMean[iIndex]) && (pRunMean[iIndex] <= dNeutralZoneHigh)) ||
            (pRunMean[iIndex] != pRunMean[iIndex]))
        {
            // it's a no-call segment
            while ((((dNeutralZoneLow < pRunMean[iIndex]) && (pRunMean[iIndex] <= dNeutralZoneHigh)) ||
                    (pRunMean[iIndex] != pRunMean[iIndex])) && (iIndex < (iProbeSetCount - 1)))
            {
              iIndex++;
            }
            iEndIndex = iIndex;
            if (iIndex < (iProbeSetCount - 1)) {iEndIndex--;}
            if (iEndIndex < iStartIndex) {iEndIndex = iStartIndex;}
            CNSegment* pSegment = new CNSegment();
            pSegment->setCall(0);
            pSegment->setConfidence(0.5);
            pSegment->setSegmentType(getSegmentType());
            pSegment->setChromosome(cChromosome);
            pSegment->setStartIndex(iStartIndex);
            pSegment->setEndIndex(iEndIndex);
            pSegment->setStartPosition(vPositions[iStartIndex]);
            pSegment->setEndPosition(vPositions[iEndIndex]);
            pSegment->setMixture(MCLASS_00);
            pSegment->setCalibratedCN(getCalibratedCN(0, pSegment->getChromosome()));
            vSegments.add(pSegment);
        }
        else if (pRunMean[iIndex] <= dNeutralZoneLow)
        {
            // it's a loss region
            dCurrentMax = pRunMean[iIndex];
            while ((pRunMean[iIndex] < dNeutralZoneLow) && (iIndex < (iProbeSetCount - 1)))
            {
                iIndex++;
                if (pRunMean[iIndex] < dCurrentMax) {dCurrentMax = pRunMean[iIndex];}
            }
            iEndIndex = iIndex;
            if (iIndex < (iProbeSetCount - 1)) {iEndIndex--;}
            if (iEndIndex < iStartIndex) {iEndIndex = iStartIndex;}

            CNSegment* pSegment = new CNSegment();
            pSegment->setCall(1);
            pSegment->setConfidence(0.5);
            pSegment->setSegmentType(getSegmentType());
            pSegment->setChromosome(cChromosome);
            pSegment->setStartIndex(iStartIndex);
            pSegment->setEndIndex(iEndIndex);
            pSegment->setStartPosition(vPositions[iStartIndex]);
            pSegment->setEndPosition(vPositions[iEndIndex]);
            pSegment->setMixture(MosaicClassNeg(getMosaicClass(dCurrentMax, m_vLossesBoundries)));
            pSegment->setCalibratedCN(getCalibratedCN(dCurrentMax, pSegment->getChromosome()));
            double tmp=pSegment->getMixtureAsDouble();
            if (((int)tmp)==tmp) {
              pSegment->setCall(0);
            }
            vSegments.add(pSegment);
        }
        else
        {
            // it's a gain region       
            dCurrentMax = pRunMean[iIndex];
            while ((pRunMean[iIndex] > dNeutralZoneHigh) && (iIndex < (iProbeSetCount - 1)))
            {
                iIndex++;
                if (pRunMean[iIndex] > dCurrentMax) {dCurrentMax = pRunMean[iIndex];}
            }
            iEndIndex = iIndex;
            if (iIndex < (iProbeSetCount - 1)) {iEndIndex--;}
            if (iEndIndex < iStartIndex) {iEndIndex = iStartIndex;}

            CNSegment* pSegment = new CNSegment();
            pSegment->setCall(1);
            pSegment->setConfidence(0.5);
            pSegment->setSegmentType(getSegmentType());
            pSegment->setChromosome(cChromosome);
            pSegment->setStartIndex(iStartIndex);
            pSegment->setEndIndex(iEndIndex);
            pSegment->setStartPosition(vPositions[iStartIndex]);
            pSegment->setEndPosition(vPositions[iEndIndex]);
            pSegment->setMixture(getMosaicClass(dCurrentMax, m_vGainsBoundries));
            pSegment->setCalibratedCN(getCalibratedCN(dCurrentMax, pSegment->getChromosome()));
            //float fMixture = pSegment->getMixture();
            double tmp=pSegment->getMixtureAsDouble();
            if (((int)tmp)==tmp) {
              pSegment->setCall(0);
            }
            vSegments.add(pSegment);
        }

#ifdef MOSAICISM_DEBUG_PSEG
        CNSegment* ts=vSegments[vSegments.size()-1];
        printf("### PSeg: new seg: idx:%d-%d pos:%d-%d mix=%d\n",
               ts->getStartIndex(),ts->getEndIndex(),
               ts->getStartPosition(),ts->getEndPosition(),
               ts->getMixture());
#endif
    }
}
Example #8
0
bool GcodeDrawer::prepareVectors()
{
    qDebug() << "preparing vectors" << this;

    QList<LineSegment*> *list = m_viewParser->getLines();
    VertexData vertex;

    qDebug() << "lines count" << list->count();

    // Clear all vertex data
    m_lines.clear();
    m_points.clear();
    m_triangles.clear();

    // Delete texture on mode change
    if (m_texture) {
        m_texture->destroy();
        delete m_texture;
        m_texture = NULL;
    }

    bool drawFirstPoint = true;
    for (int i = 0; i < list->count(); i++) {

        if (qIsNaN(list->at(i)->getEnd().z())) {
            continue;
        }

        // Find first point of toolpath
        if (drawFirstPoint) {

            if (qIsNaN(list->at(i)->getEnd().x()) || qIsNaN(list->at(i)->getEnd().y())) continue;

            // Draw first toolpath point
            vertex.color = Util::colorToVector(m_colorStart);
            vertex.position = list->at(i)->getEnd();
            if (m_ignoreZ) vertex.position.setZ(0);
            vertex.start = QVector3D(sNan, sNan, m_pointSize);
            m_points.append(vertex);

            drawFirstPoint = false;
            continue;
        }

        // Prepare vertices
        if (list->at(i)->isFastTraverse()) vertex.start = list->at(i)->getStart();
        else vertex.start = QVector3D(sNan, sNan, sNan);

        // Simplify geometry
        int j = i;
        if (m_simplify && i < list->count() - 1) {
            QVector3D start = list->at(i)->getEnd() - list->at(i)->getStart();
            QVector3D next;
            double length = start.length();
            bool straight = false;

            do {
                list->at(i)->setVertexIndex(m_lines.count()); // Store vertex index
                i++;
                if (i < list->count() - 1) {
                    next = list->at(i)->getEnd() - list->at(i)->getStart();
                    length += next.length();
//                    straight = start.crossProduct(start.normalized(), next.normalized()).length() < 0.025;
                }
            // Split short & straight lines
            } while ((length < m_simplifyPrecision || straight) && i < list->count()
                     && getSegmentType(list->at(i)) == getSegmentType(list->at(j)));
            i--;
        } else {
            list->at(i)->setVertexIndex(m_lines.count()); // Store vertex index
        }

        // Set color
        vertex.color = getSegmentColorVector(list->at(i));

        // Line start
        vertex.position = list->at(j)->getStart();
        if (m_ignoreZ) vertex.position.setZ(0);
        m_lines.append(vertex);

        // Line end
        vertex.position = list->at(i)->getEnd();
        if (m_ignoreZ) vertex.position.setZ(0);
        m_lines.append(vertex);

        // Draw last toolpath point
        if (i == list->count() - 1) {
            vertex.color = Util::colorToVector(m_colorEnd);
            vertex.position = list->at(i)->getEnd();
            if (m_ignoreZ) vertex.position.setZ(0);
            vertex.start = QVector3D(sNan, sNan, m_pointSize);
            m_points.append(vertex);
        }
    }
    m_geometryUpdated = true;
    m_indexes.clear();
    return true;
}